Catégorie:
Fréquence d'utilisation:
Difficulté:

Le design pattern Fabrique (Factory Method) définit une interface pour la création d'un objet en déléguant à ses sous-classes le choix des classes à instancier.

Description du problème

Il est fréquent de devoir concevoir une classe qui va instancier différents types d'objets suivant un paramètre fourni. Par exemple une usine va fabriquer des produits en fonction du modèle qu'on lui indique.
L'idée la plus simple pour répondre à ce besoin est d'écrire une succession de conditions qui suivant le modèle demandé, instancie et retourne l'objet correspondant.

Le problème avec cette implémentation, c'est que la classe correspondant à l'usine va être fortement couplée à tous les produits qu'elle peut instancier car elle fait appel à leur type concret.
Or ce code va être amené à évoluer régulièrement lors de l'ajout de nouveaux produits à fabriquer ou de la suppression de certains produits obsolètes.

De plus, il est fort probable que l'instanciation des différents produits soit également réalisée dans d'autres classes par exemple pour présenter un catalogue des produits fabriqués.

On se retrouve alors avec du code fortement couplé, qui risque d'être dupliqué à plusieurs endroits de l'application.


Début de solution

La première solution est de regrouper l'instanciation de tous les produits dans une seule classe chargée uniquement de ce rôle. On évite alors la duplication de code et on facilite l'évolution au niveau de la gamme des produits.

Cette solution appelée Fabrique Simple est une bonne pratique de conception mais pas un design pattern. En effet, le design pattern Fabrique est plus évolué et offre plus de flexibilité, donc attention à ne pas les confondre. Pour autant cette bonne pratique est régulièrement utilisée et s'avère efficace dans les cas les plus simples (voir son diagramme UML ci-dessous).

Digramme UML de Fabrique Simple
L'utilisateur du produit fait appel à la Fabrique Simple pour obtenir un Produit. C'est la Fabrique Simple qui est chargée d'instancier et de retourner le Produit Concret attendu (par exemple grâce à un paramètre passé en argument de la fonction). L'utilisateur du produit est donc fortement couplé uniquement à la Fabrique Simple et non à tous les produits qu'il prend en charge.

Si par la suite l'entreprise évolue et a besoin de plusieurs usines, chacune spécialisée dans la fabrication de certains produits, Fabrique Simple ne va plus suffire.
Dans ce cas il faut prévoir l'utilisation du design pattern Fabrique dont le diagramme UML est présenté ci-dessous.


Diagramme UML

Digramme UML du design pattern Fabrique

Définition de la solution

Le créateur contient toutes les méthodes permettant de manipuler les produits exceptée la méthode creerProduit qui est abstraite. Les créateurs concrets implémentent la méthode creerProduit qui instancie et retourne les produits. Chaque créateur concret peut donc créer des produits dont il a la responsabilité. Pour finir tous les produits implémentent la même interface afin que les classes utilisant les produits (comme le créateur) puissent s'y référer sans connaître les types concrets.

Si une partie de l'implémentation est identique à tous les produits concrets, alors l'interface Produit peut être une classe abstraite afin d'intégrer ce code partagé dans celle-ci. Il est également bénéfique d'utiliser ce pattern même si l'on a qu'un seul CreateurConcret ou qu'un CreateurConcret n'instancie qu'un seul Produit car les avantages liés au découplage des produits et du créateurs sont conservés.

A noter que les créateurs concrets utilisent la bonne pratique Fabrique Simple présentée précédemment. Mais comparé à cette bonne pratique qui ne sert qu'une fois, le design pattern Fabrique permet de créer une structure où l'ajout d'une sous classe (c'est à dire un créateur concret) permet de choisir les produits qui seront utilisés. C'est d'ailleurs ce qui explique la définition de ce pattern.


Conséquences

Le pattern Fabrique doit être utilisé pour découpler les clients des classes concrètes à instancier, ou si l'on ne connaît pas d'avance toutes les classes concrètes à instancier.

Pour créer des familles de produits cohérentes, on sera amené à utiliser le design pattern Fabrique Abstraite qui répond spécifiquement à ce besoin.

Exemples d'implémentations: 
Commentaires

Salut à tous les membres.

Encore merci à toi Mathieu. Mais je voulais rebondir sur la partie 'Definition de la solution': pour moi, on a deux types de méthodes à définir dans le createur:

-les méthodes abstraites qui sont toutes les méthodes qui seront redéfinites par chaque produit en fonction de leurs besoins.

- les methodes non abstraites qui ont un implémentation commune d'un produit à l'autre.

-Et je vois un constructeur dans chaque produit à la place de la méthode creerProduit.

 

 

Très bien expliqué.

Tu devrais faire plus de tutos sur les divers patterns. Y en a pas assez, même si c'est vrai que tu présentes les principaux, d'autres seraient utiles (strategy, MVC, etc.)

 

Beau boulot.

Merci pour ce tuto, vraiment agréable et facile à comprendre, c'est très clair. Merci beaucoup.

(et  j'attends tes autres articles sur d'autres design patterns!)

Enfin, je comprends clairement le truc (au moins, le cinquième site dont je lis les explications).

Merci beaucoup

Merci pour le tutoriel.

Il serait mieux de présenter les autres patterns surtouts les fondamentales aux projets standards, déjà ceux présentés ne sont pas nombreux.

Nous voulons bien profiter de ta manière aussi simple de simplifier le problème. 

Merci.

Merci pour cette explication claire, basique, mais qui nous instruit tellement mieux qu'une tonne de texte qui ne veut rien dire. Grâce à vous, je comprends enfin certain design-pattern ainsi que leurs utilités.

En espérant que vous continuerez dans l'explication de design-patterns.

Très bon tuto, continuez.

Bientôt peut-être, la rédaction du tuto du frêre de ce pattern (abstract facitory) ...

Merci

Merci Bien Mathieun, après un an de recherche sur les designs patterns, maintenant je vois clairement leur utilité, à quoi sert un design pattern dans la POO.

 

Bon travail :) 

Je vous remercie tout d'abord pour tes tutos

j’espère bien avoir ta version de dire les choses pour d'autres designs pattern

je dis ça seulement parce que je sens que tu as disparaît 

 

hello, merci pour les Topics.

j'ai une question.

J'ai ma classe Abstraite AAA qui est la Class Mère de la Class BBB et CCC.

 

- La classe AAA possède sa 1 méthode abstraite de création d'instance.

- La classe BBB possède 50 méthodes + 1 méthode héritée de AAA.

- La classe CCC possède 70 méthodes + 1 méthode héritée de AAA.

Ensuite:

- La classe BBB est instancié et est de type AAA. 

- La classe CCC est instancié et est de type AAA.

 

QUESTION:

 

Comment faire pour utiliser les méthodes de la Class BBB et de CCC sachant que celles ci sont toutes deux, de type de AAA et sans être contraint de créer 120 méthodes abstraites (50 de BBB + 70 de CCC) dans la classe Mère et les redéfinir dans les class filles.

 

Merci à toi.

 

 

 

 

@Rob : c'est impossible.

ta question se résume au paradigme suivant:

tu définis une interface I1 qui a les opérations o1 et o2

tu fais ta classe C1:I1 qui en plus de o1 et o2 a une opération f1

tu passe une instance de C1 sous forme de I1

==> f1 ne peut pas être connu connu de I1.

regarde ton problème c'est la meme chose

Factory design pattern à moi en anglais:

https://www.xoru.eu/design/factory.pdf

Thiery Brémard

Ajouter un commentaire