Interfaz para println (String)

la-g:

Me gustaría escribir código Java (digamos, un método) que imprimirá algunas líneas.

El objeto sobre el que se imprime estará a cargo de la persona que llama. Me gustaría que mi código para no importa qué es exactamente lo que es objeto y simplemente llamar a que los objetos println()o println(String)métodos. Debería funcionar si ese objeto es un java.io.PrintStream(por ejemplo System.out) o un java.io.PrintWriter(por ejemplo, construido por la persona que llama con new PrintWriter(System.out)o new PrintWriter(new ByteArrayOutputStream())).

Esto sería fácil si las clases posibles de un objeto "printlineable" compartirían alguna de las interfaces que se encomendó a la println()y println(String)métodos. Sin embargo no lo hacen.

Entonces, ¿qué puedo poner en la firma para recibir un objeto, sin violar el principio DRY escribiendo doble de lo que es esencialmente la misma aplicación, sólo con tipos intercambiadas (como tendría que cuando simplemente se sobrecarga de la función)?

public void sayHello( ??? outThingy) {
    outThingy.println("Hello World");
    outThingy.println();
    // This just a minimal example.
    // The real implementation might be more involved
    // and non-trivial, so that avoiding duplication
    // becomes a real concern.
};


// sayHello should be usable like this:

sayHello(System.out);


// but also like this:

baos = new ByteArrayOutputStream();
pw = new PrintWriter(baos)

sayHello(pw);

pw.flush();
System.out.println(baos.toString());

O si el hecho de que PrintStreamy PrintWriterno comparten este tipo de interfaz se tratará como indicación de que no son intercambiables en el sentido de proporcionar una manera de imprimir líneas? (En lugar de que el ser algún tipo de supervisión posterior histórico en el que se especifican estas clases.)

ChiefTwoPencils:

Usted puede estar interesado en un enfoque diferente, más funcional. En lugar de preocuparse por lo que ofrece cada tipo y cómo encontrar un campo común interfaceentre ellos, se puede lograr lo mismo con menos código mediante el uso de una Consumery Runnablecomo representaciones de los printlnmétodos.

// This is the common class
class FuncPrinter {
  private Consumer<String> consumer;
  private Runnable runnable;

  public FuncPrinter(PrintWriter writer) {
    consumer = writer::println;
    runnable = writer::println;
  }

  public FuncPrinter(PrintStream stream) {
    consumer = stream::println;
    runnable = stream::println;
  }

  public void println(String line) {
    consumer.accept(line);
  }

  public void println() {
    runnable.run();
  }
}

class Talker {    
  void sayHello(FuncPrinter fp) {
    fp.println("Hello World");
    fp.println();
  }
}

Y se podría utilizar de este modo:

Talker t = new Talker();

FuncPrinter fp = new FuncPrinter(System.out);
t.sayHello(fp);

ByteArrayOutputStream ostream = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(ostream);
fp = new FuncPrinter(pw);
t.sayHello(fp);

fp = new FuncPrinter(
  line -> System.out.println(line),
  () -> System.out.println(42));
t.sayHello(fp);

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=226921&siteId=1
Recomendado
Clasificación