2010-10-03 24 views
6

Mam następujące klasy, która jak widać ma raczej dość nadmiarową metodę formatNameAndAddress:W języku Java, czy mogę skonsolidować dwie podobne funkcje, w których używa JspWriter i innych PrintWriter?

package hu.flux.helper; 
import java.io.PrintWriter; 

import javax.servlet.jsp.JspWriter; 

// A holder for formatting data 
public class NameAndAddress 
{ 
public String firstName; 
public String middleName; 
public String lastName; 
public String address1; 
public String address2; 
public String city; 
public String state; 
public String zip; 

// Print out the name and address. 
public void formatNameAndAddress(JspWriter out) 
    throws java.io.IOException 
    { 
    out.println("<PRE>"); 
    out.print(firstName); 

    // Print the middle name only if it contains data. 
    if ((middleName != null) && (middleName.length() > 0)) 
    {out.print(" " + middleName);} 

    out.println(" " + lastName); 

    out.println(" " + address1); 

    if ((address2 != null) && (address2.length() > 0)) 
    out.println(" " + address2); 

    out.println(city + ", " + state + " " + zip); 
    out.println("</PRE>"); 
    } 

public void formatName(PrintWriter out) 
{ 
    out.println("<PRE>"); 
    out.print(firstName); 

    // Print the middle name only if it contains data. 
    if ((middleName != null) && (middleName.length() > 0)) 
    {out.print(" " + middleName);} 

    out.println(" " + lastName); 

    out.println(" " + address1); 

    if ((address2 != null) && (address2.length() > 0)) 
    out.println(" " + address2); 

    out.println(city + ", " + state + " " + zip); 
    out.println("</PRE>"); 
} 
} 

Chciałbym przepisać klasę użyć metody rodzajowe jak:

 // Print out the name and address. 
private void genericFormatNameAndAddress(Object out) 
{ 
    out.println("<PRE>"); 
    out.print(firstName); 

    // Print the middle name only if it contains data. 
    if ((middleName != null) && (middleName.length() > 0)) 
    {out.print(" " + middleName);} 

    out.println(" " + lastName); 

    out.println(" " + address1); 

    if ((address2 != null) && (address2.length() > 0)) 
    out.println(" " + address2); 

    out.println(city + ", " + state + " " + zip); 
    out.println("</PRE>"); 
} 

Ale nie mogę tego zrobić dokładnie tak, ponieważ Object nie ma metod print() i println(). Jeśli wyrzucę dane wyjściowe do JspWriter lub PrintWriter, czasami będę je rzucał w niewłaściwy sposób.

Wyobrażam sobie, co muszę zrobić, to przekazać typ obiektu jako zmienną, a następnie użyć zmiennej do określenia sposobu rzutowania. czy to możliwe? Jeśli tak to jak? Jeśli nie, jakie byłoby dobre rozwiązanie?

Odpowiedz

5

to prawdopodobnie będzie działać:

public void formatNameAndAddress(JspWriter out) throws java.io.IOException { 
    formatNameAndAddress(new PrintWriter(out)); 
} 
+0

To działa, okrzyki! –

+0

Wiedząc, że mogę rzucić JspWriter do PrintWriter, próbowałem nieco zmienić moją wersję (włączając w to mądrość Steve'a) ... Jednak teraz mam nowy problem, o który pytam na http: // stackoverflow.com/questions/3850079/shouldnt-a-method-that-receives-java-lang-object-as-input-also-receive-javax-ser –

+0

@Brian, nie, którego nie można obsłużyć, 'JspWriter' nie jest podklasa 'PrintWriter'. –

1

Ty niby muddling dwa różne zadania z tych metod, a łamiąc zasadę OO specjalizacji. Oznacza to, że masz metody, które są odpowiedzialne za formatowanie jednego z dwóch typów łańcuchów ... ORAZ odpowiedzialne za przesłanie ich do jednego z dwóch typów docelowych wyników.

Lepszym podejściem może być uelastycznienie metod. Oznacza to, że TYLKO będą odpowiedzialni za budowanie łańcucha "Nazwa" lub "Nazwa i Adres" i zwracanie String jako typu zwrotu metod.

W punkcie kodu, w którym wywołuje się te metody, oczywiście masz już obiekt JspWriter lub PrintWriter ... ponieważ teraz przekazujesz go jako argument metody. Tak więc byłoby czysto po prostu zostawić ten obiekt w kodzie i wydrukować go, co jest zwracane przez wyspecjalizowaną metodę agnostyczną.

+0

W rzeczywistości oba ostatecznie mają ten sam docelowy wynik. Jedna metoda jest wywoływana z serwletu, a druga ze strony JSP, którą rozumiem, jest faktycznie zmieniana na serwlet przed dostarczeniem. Ale myślę, że rozumiem, co sugerujesz. Pozdrawiam za odpowiedź! –

0

Jeśli chcesz oddać obiekt do prawidłowego Writer można spróbować coś takiego:

private void genericFormatNameAndAddress(Object out){ 
    if (obj instanceof Printwriter){ 
     //cast to printwriter 
    } else { 
     //cast to JspWriter 
    } 

Barkers rozwiązanie wydaje się być lepiej przystosowane ponieważ PrintWriter może być zbudowana z pomocą JspWriter.

+0

Pozdrawiam za odpowiedź, ale nie sądzę, że tak naprawdę zrobiłbym to, czego szukam, ponieważ spowodowałoby to, że kod byłby dłuższy i bardziej skomplikowany, gdybym sprawdzał przed każdym przypadkiem odlewania i nie byłoby zbyt wiele korzyści z przejścia "out" do tej funkcji, jeśli byłby ponownie rozdzielony i przetworzony osobno. –

0

Zarówno JspWriter, jak i PrintWriter są podklasami java.io.Writer. Ponieważ nie używać żadnych funkcji, które są specyficzne dla żadnej z tych dwóch, można zadeklarować jako metodę robienia java.io.Writer:

public void formatNameAndAddress(Writer out) throws java.io.IOException 
{ 
    [...] 

Następnie przekazać JspWriter lub PrintWriter w miarę potrzeb.

Edit: To nie będzie działać właściwie bez modyfikowania kodu, ponieważ, jak podkreślił innymi Writer nie posiada print i println metod, natomiast JspWriter i PrintWriter zarówno zapewnić im.

+0

'println' nie jest w' Writer', jest zarówno w 'JspWriter' i' PrintWriter' ale nadal jest charakterystyczne dla każdej z tych klas. –

+0

Próbowałem tego, ale ten podpis nie chwyta JspWriter. Zbadałem podobne podejście i opublikowałem pytanie wynikające z tej jak dotąd nieprzyjemnej przygody na http://stackoverflow.com/questions/3850079/shouldnt-a-method-that-receives-java-lang-object- as-input-also-receive-javax-ser –