No cache version.

Caching disabled. Default setting for this page:enabled (code LNG204)
If the display is too slow, you can disable the user mode to view the cached version.

Le modèle fabrication(Factory Method Pattern)

Le pattern factory method selon l'ouvrage "Design Patterns: Elements of Reusable Object-Oriented Software" du GOF.

Alias

  • Fr : modèle fabrication, Constructeur Virtuel
  • Angl : factory method pattern, virtual constructor

Intention de factory method

Le pattern factory method définit une interface pour la création d'un objet en laissant à des sous-classes le choix des classes à instancier.

Contents Haut

Motivation de factory method

GOF exemple de factory method patternConcreteCreatorConcreteProductCreatorProductAgrégation d'objets de type Document

Les utilisent des classes abstraites pour définir et gérer les relations entre les objets. Un framework est souvent responsable de la création de ces objets.

Considérons un framework pour des aplications qui présentent des documents multiples à l'utilisateur. Deux clés abstraites fondamentales de ce framework sont les classes Application et Document. Nous devons dériver des sous-classes concrètes pour réaliser les implémentations spécifiques de ces deux classes. Pour créer une application de dessin par exemple, nous devons créer les classes DrawingApplication et DrawingDocument. La classe Application est responsable de la gestion des Documents, et de leur création si nécessaire - lorsque l'utilisateur sélectionne Open ou New dans un menu, par exemple.

Puisque la sous-classe particulière de Document à instancier est dépendante du type d'application, la classe Application ne peut prévoir la sous-classe de Document qu'il convient d'instancier - la classe Application connait seulement le moment où un Document doit être créé, mais pas le type de Document à créer. Cette situation crée un dilemne : le framework doit instancier des classes, mais il ne connait que des classes abstraites, qui ne peuvent être instanciées.

Le pattern factory method nous offre donc une solution : encapsuler la connaissance du type de sous-classe de Document à créer, et déplacer cette connaissance hors du framework.

Les sous-classes d'Application redéfinissent par surcharge une opération abstraite d'Application nommée createDocument, afin de retourner la sous-classe de Document qui convient. Dès qu'une sous-classe Application est instanciée, elle peut à son tour instancier des Documents spécifiques de l'Application, sans connaître leur classe. La méthode createDocument est une factory method car elle est responsable de la fabrication d'un objet.

Contents Haut

Utilisation de factory method

Le modèle fabrique peut nous aider dans les cas suivants :

  • Une classe ne peut prévoir la classe des objets qu'elle devra créer.
  • Une classe désire que ses sous-classes spécifient les objets qu'elle crée
  • Les classes délèguent des responsabilités à une de leurs nombreuses sous-classes assistantes, et nous désirons localiser le fait de savoir quelle sous-classe assistante a reçu cette délégation.

Contents Haut

Structure de factory method

GOF structure factory method patternProductCreatorConcreteCreatorConcreteProduct

Contents Haut

Constituants de factory method

  • Product (produit abstrait ou interface)
    Définit l'interface des objets créés par l'opération factoryMethod. Dans le cadre de notre exemple, le produit est Document.
  • ConcreteProduct (produit concret)
    Implémente l'interface Product. Dans le cadre de notre exemple, le produit concret est MyDocument.
  • Creator (facteur - traduction discutable )
    Déclare l'opération factoryMethod qui retourne un objet de type Product. Creator peut aussi définir une implémentation par défaut de factoryMethod, qui retourne un objet ConcreteProduct par défaut. Il peut en outre faire un appel à factoryMethod pour créer un objet Product. Dans le cadre de notre exemple, le facteur est Application.
  • ConcreteCreator (facteur concret)
    Override (surcharge) l'opération factoryMethod pour retourner une instance du ConcreteProduct approprié. Dans le cadre de notre exemple, le facteur concret est MyApplication.

Contents Haut

Collaborations de factory method

Creator confie à ses sous-classes le soin de la définition de la fabrication, de sorte qu'il renvoie une instance du ConcreteProduct approprié.

Contents Haut

Conséquences de factory method

Avantages du factory method pattern :

Factory method pattern élimine le besoin d'incorporer des classes spécifiques à l'application dans notre code. Le code ne concerne que l'interface Product; nous pouvons le faire fonctionner avec toute classe produit concret que nous définissons, pourvu qu'elle implémente Product.

Un inconvénient potentiel des méthodes factory réside dans le fait que les clients peuvent avoir à dériver (sous-classer) la classe Creator simplement pour créer un objet produit concret particulier. Sous-classer peut être rentable lorsque nous devons de toute manière dériver des sous-classes de Creator.

Hébergement des sous-classes. Nous pouvons plus aisément créer des objets à l'intérieur d'une classe à l'aide d'une méthode factory que de les créer directement.

Interconnection des hiérarchies parallèles de classes. Nous avons des hiérarchies de classes parallèles quand une classe délègue certaines de ses responsabilités à une classe séparée.

Contents Haut

Implémentation de factory method

Deux variantes principales :

  • Creator est une classe abstraite et ne fournit pas d'implémentation pour la fabrication qu'elle déclare.
  • Creator est une classe concrète qui fournit une implémentation par défaut pour la fabrication.

NB : nous pouvons aussi plus rarement trouver le cas d'une classe abstraite qui fournit une implémentation par défaut.

Fabrication paramétrée. Dans ce cas, nous permettons à la méthode factory de créer de nombreuses espèces de produits. La méthode factory utilise alors un paramètre pour déterminer le type d'objet à créer, pourvu que chaque type implémente Product.

Contents Haut

Exemples de codes

  1. using System;
  2. class Document
  3. {
  4. public:
  5. virtual void setPosition( int x, int y ) =0 ;
  6. virtual void redisplay() =0 ;
  7. //...
  8. } ;
  9. class Application
  10. {
  11. public:
  12. int run()
  13. {
  14. //...
  15. newDocument() ;
  16. //...
  17. moveDocument(3,5) ;
  18. //...
  19. }
  20. protected:
  21. virtual void newDocument() =0 ;
  22. Document * doc_ ;
  23. private:
  24. void moveDocument( int x, int y )
  25. {
  26. doc_->setPosition(x,y) ;
  27. doc_->redisplay() ;
  28. }
  29. } ;
  30. //...
  31. class WordDocument: public Document
  32. {
  33. public:
  34. void setPosition( int x, int y ) { /***/ }
  35. void redisplay() { /***/ }
  36. //...
  37. }
  38. class Word: public Application
  39. {
  40. protected:
  41. void newDocument() { doc_ = new WordDocument ; }
  42. }
  43. int main()
  44. {
  45. Word appli ;
  46. appli.run() ;
  47. }


  1. public abstract class Editor {
  2. private Document doc;
  3. public abstract Document createDocument();
  4. public void newDocument() {
  5. doc = createDocument();
  6. doc.open();
  7. }
  8. public void saveDocument() {
  9. if (doc != null)
  10. doc.save();
  11. }
  12. public void closeDocument() {
  13. if (doc != null)
  14. doc.close();
  15. }
  16. }
  17. public class RTFEditor extends Editor {
  18. public Document createDocument() {
  19. return new RTFDocument();
  20. }
  21. }
  22. public abstract class Document {
  23. public abstract void open();
  24. public abstract void save();
  25. public abstract void close();
  26. }
  27. public class RTFDocument extends Document {
  28. public void RTFDocument() {
  29. System.out.println("RTF Document Created");
  30. }
  31. public void open() {
  32. System.out.println("RTF Document Open");
  33. }
  34. public void save() {
  35. System.out.println("RTF Document Saved");
  36. }
  37. public void close() {
  38. System.out.println("RTF Document Closed");
  39. }
  40. }
  41. public class Main {
  42. public static void main(String[] args) {
  43. Editor editor = new RTFEditor();
  44. editor.newDocument();
  45. editor.saveDocument();
  46. editor.closeDocument();
  47. }
  48. }

Contents Haut

  • Abstract Factory
  • Template Methods
  • Prototype

English translation

You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.

If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.

Thank you in advance.

Document created the 08/10/2005, last modified the 26/10/2018
Source of the printed document:https://www.gaudry.be/en/pattern-factory-method.html

The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.