Metodi di fabbrica

D: Durante il "Polimorfismo nella sua forma più pura", ho visto il termine insolito metodo di fabbrica. Potresti descrivere cos'è un metodo di fabbrica e spiegare come posso usarlo?

A: Consideriamo un esempio.

Ogni programma ha bisogno di un modo per segnalare gli errori. Considera la seguente interfaccia:

Listato 1

interfaccia pubblica Trace {// attiva e disattiva il debug public void setDebug (boolean debug); // scrive un messaggio di debug public void debug (String message); // scrive un messaggio di errore public void error (String message); }

Supponi di aver scritto due implementazioni. Un'implementazione (Listato 2) scrive i messaggi sulla riga di comando, mentre un'altra (Listato 3) li scrive su un file.

Listato 2

la classe pubblica FileTrace implementa Trace {private java.io.PrintWriter pw; debug booleano privato; public FileTrace () lancia java.io.IOException {// un vero FileTrace avrebbe bisogno di ottenere il nome del file da qualche parte // per l'esempio lo codificherò come hardcoded pw = new java.io.PrintWriter (new java.io.FileWriter (" c: \ trace.log ")); } public void setDebug (boolean debug) {this.debug = debug; } public void debug (String message) {if (debug) {// stampa solo se debug è vero pw.println ("DEBUG:" + messaggio); pw.flush (); }} public void error (String message) {// stampa sempre gli errori pw.println ("ERROR:" + message); pw.flush (); }}

Listato 3

la classe pubblica SystemTrace implementa Trace {debug booleano privato; public void setDebug (boolean debug) {this.debug = debug; } public void debug (String message) {if (debug) {// print only if debug is true System.out.println ("DEBUG:" + message); }} public void error (String message) {// stampa sempre gli errori System.out.println ("ERROR:" + message); }}

Per utilizzare una di queste classi, è necessario eseguire le seguenti operazioni:

Listato 4

// ... un po 'di codice ... SystemTrace log = new SystemTrace (); // ... codice ... log.debug ("entrare in loog"); // ... eccetera ...

Ora, se desideri modificare l' Traceimplementazione utilizzata dal tuo programma, dovrai modificare ogni classe che istanzia Traceun'implementazione. A seconda del numero di classi utilizzate Trace, potrebbe essere necessario molto lavoro per apportare la modifica. Inoltre, vuoi evitare di alterare il più possibile le tue classi.

Un metodo factory ci consente di essere molto più intelligenti su come le nostre classi ottengono Traceistanze di implementazione:

Listato 5

public class TraceFactory {public static Trace getTrace () {return new SystemTrace (); }}

getTrace()è un metodo di fabbrica. Ora, ogni volta che vuoi ottenere un riferimento a Trace, puoi semplicemente chiamare TraceFactory.getTrace():

Listato 6

// ... un po 'di codice ... Trace log = new TraceFactory.getTrace (); // ... codice ... log.debug ("entrare in loog"); // ... eccetera ...

L'utilizzo di un metodo di fabbrica per ottenere un'istanza può farti risparmiare molto lavoro in seguito. Nel codice precedente, TraceFactoryrestituisce le SystemTraceistanze. Immagina di nuovo che le tue esigenze cambino e che tu debba scrivere i tuoi messaggi su un file. Tuttavia, se si utilizza un metodo factory per ottenere la propria istanza, è necessario apportare una sola modifica in una classe per soddisfare i nuovi requisiti. Non è necessario apportare modifiche in ogni classe che utilizza Trace. Invece puoi semplicemente ridefinire getTrace():

Listato 7

public class TraceFactory {public static Trace getTrace () {try {return new FileTrace (); } catch (java.io.IOException ex) {Trace t = new SystemTrace (); t.error ("non ha potuto istanziare FileTrace:" + ex.getMessage ()); return t; }}}

Inoltre, i metodi factory si dimostrano utili quando non si è sicuri di quale implementazione concreta di una classe istanziare. Invece, puoi lasciare quei dettagli al metodo di fabbrica.

Negli esempi precedenti il ​​tuo programma non sapeva se creare FileTraceo SystemTraceistanze. Invece, puoi programmare i tuoi oggetti in modo che usino semplicemente Tracee lasciare l'istanza dell'implementazione concreta a un metodo factory.

Tony Sintes è un consulente principale di BroadVision. Programmatore Java 1.1 certificato Sun e sviluppatore Java 2, lavora con Java dal 1997.

Ulteriori informazioni su questo argomento

  • La prima tappa per tutte le tue esigenze di pattern può essere trovata nel famoso libro Gang of Four Design Patterns, Eric Gamma, Richard Helm, Ralph Johnson, John Vlissides (Addison-Wesley, 1995)

    //www.amazon.com/exec/obidos/ASIN/0201633612/javaworld

  • Voglio di più? Vedere l' indice di domande e risposte Java per il catalogo completo di domande e risposte

    //www.javaworld.com/javaworld/javaqa/javaqa-index.html

  • Per oltre 100 suggerimenti penetranti Java da alcune delle migliori menti del settore, visita 'JavaWorld s Tips Java Indice

    //www.javaworld.com/javatips/jw-javatips.index.html

  • Per altri articoli rivolti ai nuovi programmatori Java, visita la sezione Intro Level dell'Indice degli argomenti di JavaWorld

    //www.javaworld.com/javaworld/topicalindex/jw-ti-introlevel.html

  • Parla nella discussione per principianti su Java

    //www.itworld.com/jump/jw-javaqa/forums.itworld.com/[email protected]@.ee6b804/1195!skip=1125

  • Ricevi suggerimenti settimanali sulla programmazione Java iscrivendoti alla nostra newsletter e-mail gratuita di Java Tutor

    //reg.itworld.com/cgi-bin/subcontent12.cgi

Questa storia, "Metodi di fabbrica" ​​è stata originariamente pubblicata da JavaWorld.