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.
Motivation de factory method
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.
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.
Structure de factory method
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 - )
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.
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é.
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.
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.
Exemples de codes
Code c++ (Document - Factory Method Pattern) (47 lignes)
using System; class Document { public: virtual void setPosition( int x, int y ) =0 ; virtual void redisplay() =0 ; //... } ; class Application { public: int run() { //... newDocument() ; //... moveDocument(3,5) ; //... } protected: virtual void newDocument() =0 ; Document * doc_ ; private: void moveDocument( int x, int y ) { doc_->setPosition(x,y) ; doc_->redisplay() ; } } ; //... class WordDocument: public Document { public: void setPosition( int x, int y ) { /***/ } void redisplay() { /***/ } //... } class Word: public Application { protected: void newDocument() { doc_ = new WordDocument ; } } int main() { Word appli ; appli.run() ; }
Code Java (Editor, RTFEditor, Document, RTFDocument) (48 lignes)
public abstract class Editor { public void newDocument() { doc = createDocument(); doc.open(); } public void saveDocument() { if (doc != null) doc.save(); } public void closeDocument() { if (doc != null) doc.close(); } } public class RTFEditor extends Editor { return new RTFDocument(); } } public abstract void open(); public abstract void save(); public abstract void close(); } public void RTFDocument() { } public void open() { } public void save() { } public void close() { } } public class Main { Editor editor = new RTFEditor(); editor.newDocument(); editor.saveDocument(); editor.closeDocument(); } }
Patterns apparentés au factory method
- 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.