Могу ли я объединить две похожие функции в Java, где используется JspWriter и другой PrintWriter? - PullRequest
6 голосов
/ 03 октября 2010

У меня есть следующий класс, который, как вы увидите, имеет довольно избыточный метод formatNameAndAddress:

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("");
    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("
"); } public void formatName (PrintWriter out) { out.println ( "
");
  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("
"); } }

Я хотел бы переписать класс для использования универсального метода, такого как:

     // Print out the name and address.
 private void genericFormatNameAndAddress(Object out)
 {
  out.println("");
   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("
"); }

Но я не могу сделать это в точности так, потому что Object не имеет методов print () и println (). Если я приведу вывод к JspWriter или PrintWriter, я буду иногда приводить его неправильно.

Я представляю, что мне нужно как-то передать тип объекта как переменную, а затем использовать переменную для определения способа приведения. Это возможно? Если так, то как? Если нет, то что было бы хорошим решением?

Ответы [ 4 ]

5 голосов
/ 03 октября 2010

Это, вероятно, будет работать:

public void formatNameAndAddress(JspWriter out) throws java.io.IOException {
    formatNameAndAddress(new PrintWriter(out));
}
1 голос
/ 03 октября 2010

Этими методами вы путаете две разные задачи и нарушаете принцип специализации ОО. То есть у вас есть методы, которые отвечают за форматирование одного из двух типов строк ... И отвечают за отправку их одному из двух типов выходных целей.

Лучше всего сделать ваши методы более специализированными. То есть, они должны отвечать ТОЛЬКО за построение строки «Имя» или «Имя и адрес» ... и возвращать String в качестве типа возврата метода.

В той точке кода, где вы вызываете эти методы, у вас, очевидно, уже есть объект JspWriter или PrintWriter ... потому что сейчас вы передаете его как аргумент метода. Поэтому было бы чётче просто оставить этот объект там, где он есть в коде, и распечатать его String, который возвращается вашим специализированным методом, независимым от вывода.

0 голосов
/ 03 октября 2010

И JspWriter, и PrintWriter являются подклассами java.io.Writer.Поскольку вы не используете какую-либо функциональность, относящуюся к какому-либо из двух, вы можете объявить метод как java.io.Writer:

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

, а затем передать JspWriter или PrintWriter, как требуется.

Редактировать: Это не сработает без фактического изменения кода, поскольку, как отмечали другие, Writer не имеет методов print и println, тогда какJspWriter и PrintWriter оба предоставляют их.

0 голосов
/ 03 октября 2010

Если вы хотите привести объект к правильному Writer, вы можете попробовать что-то вроде:

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

Решение Barkers кажется более подходящим, потому что Printwriter может быть создан из JspWriter.

...