Académique Documents
Professionnel Documents
Culture Documents
Intention
Le patron Abstract Factory fournit une interface pour créer des familles d'objets liés
ou dépendants sans spécifier leurs classes concrètes.
Objectif :
Exemple classique :
Lorsqu’une classe gère plusieurs types de produits, déplacer les méthodes fabrique
dans des fabriques individuelles ou dans une implémentation à part entière d’une
fabrique abstraite est souvent plus pratique.
Problème
On souhaite pouvoir créer dynamiquement des familles d'objets apparentés (par
exemple des instances d'une même classe), tout en permettant de reporter certaines
décisions jusqu'à la phase d'exécution (par exemple le choix d'une classe concrète
pour réaliser une interface donnée).
Solution
Créer des familles de produits liés fonctionnellement avec plusieurs fabriques, donc
on obtient plusieurs types d'objets retournés par chaque fabrique (plusieurs
méthodes d'instanciation par Factory method).
Principe de base du patron Abstract Factory
Pour ce faire, il faut définir des interfaces pour chaque produit de la famille de
produits. Toutes les autres variantes de produits peuvent ensuite se servir de ces
interfaces. Ensuite, définir la fabrique abstraite, une interface contenant une liste de
méthodes de création pour toutes les familles de produits. Ces méthodes doivent
renvoyer tous les types de produits abstraits des interfaces déjà créées.
Pour chaque variante d’une famille de produits, définir une classe fabrique qui
retourne un certain type de produits et qui implémente l’interface FabriqueAbstraite.
Enfin, le client travaille simultanément avec les interfaces abstraites des fabriques et
des produits.
Structure
Diagramme UML du patron Abstract Factory
1. Le client envoie une requête à AbstractFactory pour ConcreteFactory1.
2. L'AbstractFactory crée une instance de ConcreteFactory1 et la renvoie.
3. Le client envoie une requête à ConcreteFactory1 pour la création de ProductA.
4. ConcreteFactory1 crée une instance de ProductA1 qui est membre de Family1 et
la renvoie.
5. Maintenant, le client envoie une requête à AbstractFactory pour
ConcreteFactory2.
6. L'AbstractFactory crée une instance de ConcreteFactory2.
7. Le client envoie une requête à ConcreteFactory2 pour la création de ProductA.
8. La ConcreteFactory2 crée une instance de ProductA2 qui est membre de
Family2 et la renvoie.
Participants
● AbstractFactory déclare l'interface pour les opérations qui créent des objets
abstraits,
● ConcreteFactory implémente les opérations qui créent les objets concrets,
● AbstractProduct déclare une interface pour un type d'objet,
● ConcreteProduct définit un objet qui doit être créé par la fabrique concrète
correspondante et implémente l'interface AbstractProduct.
Le Client utilise seulement les interfaces déclarées par AbstractFactory et par les
classes AbstractProduct
Collaborations & implémentation
Une seule instance de fabrique concrète est créée à l'exécution. Cette fabrique crée
les objets avec une implémentation spécifique.
Pour créer différentes sortes d'objets, les clients doivent utiliser différentes fabriques
concrètes. La fabrique abstraite défère la création des objets à ses sous-classes
concrètes
Implémentation
Les fabriques sont souvent des singletons. Ce sont les sous-classes concrètes qui
font la création, en utilisant le plus souvent une Factory Method.
Chaque fabrique possède sa propre variante de produit, tous ses produits seront
compatibles. Il suffit donc de créejurste une nouvelle classe concrète Fabrique et
passez-la au code client.
En effet, ce dernier manipule les fabriques et les produits uniquement via leurs
interfaces abstraites, ce qui lui permet de travailler avec n’importe quelle variante de
produit créée par un objectFactory.
Conséquences :
● Isolation des classes concrètes,
● Echange facile des familles de produit,
● Encouragement de la cohérence entre les produits,
● Prise en compte difficile de nouvelles formes de produit.
Exemple illustratif
En continuant avec l’exemple de fabrication de télephones, nous constatons quelque
soit la façon dont l'usine divise l'abstraction, les deux modèles (Simple Factory et
Factory Method) ne concernent qu'un seul type de produit Téléphone (produit
abstrait). Si vous souhaitez générer un autre produit Laptop, vous ne pouvez pas, il
faut utiliser Abstract Factory pour créer une Usine de Laptop.
Avec Factory Method, nous devons copier et modifier complètement tout le code de
gestion de la production du téléphone et le faire avec Laptop. Évidemment, ce n’est
pas une bonne manière propice à l'expansion et à la maintenance.
Vous devez modifier la définition des classes liées à la fabrique en ajoutant une
interface de fabrication de produits Laptop à la Classe AbstractFactory :
public interface AbstractFactory {
Phone makePhone();
Laptop makeLaptop();
}
Avantages et inconvénients
Avantages
● Encapsuler la création d'objets, vous pouvez contrôler les classes d'objets
créées par une application. De plus, le client ne connaît pas l'implémentation
concrète et ne peut passer que par l'interface ou la classe abstraite.
● Favoriser la cohérence entre les familles d'objets car il garantit que si une
famille d'objets est conçue pour fonctionner ensemble, l'application utilise les
objets d'une famille à la fois. Avec ce patron, c'est très facile à réaliser.
● Éviter le couplage étroit entre les produits concrets et le code client.
Inconvénients
● Ajouter une nouvelle famille d'objets ne sera pas aisé car la super-usine de
l'Abstract Factory (interface ou classe abstraite) fixe les familles d'objets qui
peuvent être créées. Cela nous obligera à changer la fabrique abstraite et
toutes les sous-classes.
Questions
Question 1.
Le Factory est une terminologie qui désigne une classe ou une méthode
responsable de la création/production d'un objet. Ex. : PhoneFactory est
responsable de la production des téléphones.
Réponse à la question 2
Dans cet exemple, makePhone() est la méthode de fabrique qui produit des
téléphones en fonction de l'argument phoneType qu'il reçoit.
Réponse à la question 3
● Factory ou simple Factory : quand le client a juste besoin d'une classe et ne
se soucie pas de l'implémentation concrète qu'il obtient.
● Factory Method : quand le client ne sait pas quelles classes concrètes il devra
créer au moment de l'exécution, mais souhaite simplement obtenir une classe
qui fera le travail.
● Abstact Factory : lorsque votre système doit créer plusieurs familles de
produits ou que vous souhaitez fournir une bibliothèque de produits sans
exposer les détails de mise en œuvre.
Les classes abstraites Factory sont souvent implémentées avec Factory Method.
Les méthodes d'usine sont généralement appelées dans les méthodes de modèle.