Méthodes d'usine

Q: En passant par "Le polymorphisme dans sa forme la plus pure", j'ai vu le terme de méthode d'usine inconnu. Pourriez-vous s'il vous plaît décrire ce qu'est une méthode d'usine et expliquer comment je peux l'utiliser?

R: Prenons un exemple.

Chaque programme a besoin d'un moyen de signaler les erreurs. Considérez l'interface suivante:

Liste 1

public interface Trace {// activer et désactiver le débogage public void setDebug (débogage booléen); // écrire un message de débogage public void debug (String message); // écrire un message d'erreur public void error (String message); }

Supposons que vous ayez écrit deux implémentations. Une implémentation (Listing 2) écrit les messages sur la ligne de commande, tandis qu'une autre (Listing 3) les écrit dans un fichier.

Liste 2

classe publique FileTrace implémente Trace {private java.io.PrintWriter pw; débogage booléen privé; public FileTrace () lance java.io.IOException {// un vrai FileTrace aurait besoin d'obtenir le nom de fichier quelque part // pour l'exemple je le coderai en dur pw = new java.io.PrintWriter (new java.io.FileWriter (" c: \ trace.log ")); } public void setDebug (débogage booléen) {this.debug = debug; } public void debug (String message) {if (debug) {// n'imprime que si debug est vrai pw.println ("DEBUG:" + message); pw.flush (); }} public void error (String message) {// toujours afficher les erreurs pw.println ("ERROR:" + message); pw.flush (); }}

Liste 3

classe publique SystemTrace implémente Trace {débogage booléen privé; public void setDebug (débogage booléen) {this.debug = debug; } public void debug (String message) {if (debug) {// seulement imprimer si debug est vrai System.out.println ("DEBUG:" + message); }} public void error (String message) {// toujours afficher les erreurs System.out.println ("ERROR:" + message); }}

Pour utiliser l'une de ces classes, vous devez effectuer les opérations suivantes:

Liste 4

// ... du code ... SystemTrace log = new SystemTrace (); // ... code ... log.debug ("entrer dans le loog"); // ... etc ...

Maintenant, si vous souhaitez modifier l' Traceimplémentation utilisée par votre programme, vous devrez modifier chaque classe qui instancie une Traceimplémentation. En fonction du nombre de classes utilisées Trace, il vous faudra peut-être beaucoup de travail pour effectuer le changement. De plus, vous voulez éviter autant que possible de modifier vos cours.

Une méthode de fabrique nous permet d'être beaucoup plus intelligents sur la façon dont nos classes obtiennent des Traceinstances d'implémentation:

Liste 5

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

getTrace()est une méthode d'usine. Désormais, chaque fois que vous souhaitez obtenir une référence à a Trace, vous pouvez simplement appeler TraceFactory.getTrace():

Liste 6

// ... du code ... Trace log = new TraceFactory.getTrace (); // ... code ... log.debug ("entrer dans le loog"); // ... etc ...

L'utilisation d'une méthode d'usine pour obtenir une instance peut vous faire économiser beaucoup de travail plus tard. Dans le code ci-dessus, TraceFactoryrenvoie des SystemTraceinstances. Imaginez à nouveau que vos exigences changent et que vous devez écrire vos messages dans un fichier. Cependant, si vous utilisez une méthode de fabrique pour obtenir votre instance, vous ne devez effectuer qu'une seule modification dans une classe afin de répondre aux nouvelles exigences. Vous n'avez pas besoin d'apporter des modifications dans chaque classe qui utilise Trace. Au lieu de cela, vous pouvez simplement redéfinir getTrace():

Liste 7

public class TraceFactory {public static Trace getTrace () {try {return new FileTrace (); } catch (java.io.IOException ex) {Trace t = new SystemTrace (); t.error ("n'a pas pu instancier FileTrace:" + ex.getMessage ()); return t; }}}

De plus, les méthodes de fabrique s'avèrent utiles lorsque vous ne savez pas quelle implémentation concrète d'une classe instancier. Au lieu de cela, vous pouvez laisser ces détails à la méthode d'usine.

Dans les exemples ci - dessus votre programme ne sait pas si vous souhaitez créer FileTraceou SystemTraceinstances. Au lieu de cela, vous pouvez programmer vos objets pour utiliser simplement Traceet laisser l'instanciation de l'implémentation concrète à une méthode d'usine.

Tony Sintes est consultant principal chez BroadVision. Programmeur Java 1.1 et développeur Java 2 certifié Sun, il travaille avec Java depuis 1997.

En savoir plus sur ce sujet

  • Le premier arrêt pour tous vos besoins en matière de motifs se trouve dans le célèbre livre Gang of Four Design Patterns, Eric Gamma, Richard Helm, Ralph Johnson, John Vlissides (Addison-Wesley, 1995)

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

  • Vouloir plus? Consultez l' index des questions-réponses Java pour le catalogue complet des questions-réponses

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

  • Pour plus de 100 conseils Java perspicaces de certains des meilleurs esprits dans l'entreprise, visitez le JavaWorld » s Java Conseils index

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

  • Pour plus d 'articles destinés aux nouveaux programmeurs Java, visitez la section Niveau d ' introduction de l ' index des sujets de JavaWorld

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

  • Exprimez-vous dans la discussion Java Beginner

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

  • Recevez chaque semaine des conseils de programmation Java en vous abonnant à notre newsletter gratuite par e-mail Java Tutor

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

Cette histoire, "Méthodes d'usine" a été initialement publiée par JavaWorld.