Le modèle fabrique abstraite(Abstract Factory Pattern)
Le pattern abstract factory selon l'ouvrage "Design Patterns: Elements of Reusable Object-Oriented Software" du GOF.
Alias
- Fr : modèle fafrique abstraite
- Angl : abstract factory, kit
Intention de abstract factory
Le pattern abstract factory fournit une interface pour la création de familles d'objets apparentés ou indépendants sans devoir spécifier leurs classes concrètes.
Motivation de abstract factory
Considérons une boite à outils interface utilisateur qui supporte de multiples look and feels (apparences) standards tels que Motif et Presentation Manager. Les comportements spécifiques de certains éléments (widgets) de l'interface graphique (tels que les scrollbars - ascenceurs, ou ls boutons) peuvent varier en fonction du look and feel utilisé. pour qu'une application soit portable indépendament de l'apparence utilisée, ces widgets ne doivent pas être codés en dur pour une apparence donnée. Si nous instancions des classes de widgets spécifiques d'une apparence dans l'application, nous ne pourons difficilement changer l'apparence ultérieurement.
Nous pouvons résoudre ce problème en utilisant une classe abstraite WidgetsFactory qui définit une interface pour la création de toute variété de widgets. Nous devons de même définir une classe abstraite pour chaque variété de widget, dont les sous-classes concrètes implémenteront les versions de ces widgets conformément aux standards des apparences supportées. L'interface WidgetFactory possède une opération qui retourne un nouvel objet widget pour chaque classe abstraite de widgets. Les clients peuvent appeler ces opérations pour obtenir des instances de widgets sans savoir quelles classes concrètes ils utilisent. De cette manière, le client reste indépendant de l'apparence utilisée.
Utilisation de abstract factory
Le modèle fabrique abstraite peut nous aider dans les cas suivants :
- Un système doit être indépendant de la manière dont ses produits ont été créés, combinés, et représentés.
- Un système doit être constitué à partir d'une famille de produits, parmi plusieurs.
- Nous souhaitons renforcer le caractère communauté d'une famille d'objets produits concus pour être utilisés ensemble.
- Nous souhaitons fabriquer une bibliothèque de classes de produits, en n'en révélant que l'interface et non l'implémentation.
Structure de abstract factory
Constituants de abstract factory
- AbstractFactory (fabrique abstraite)
Déclare une interface contenant les opérations de création d'objets produits abstraits. Dans notre exemple, la fabrique abstraite est WidgetFactory. - ConcreteFactory (fabrique concrète)
Implémente les opérations de création d'objets produits concrets. Dans notre exemple, les fabriques concrètes sont MotifWidgetFactory et PMWidgetFactory. - AbstractProduct (produit abstrait)
Déclare une interface pour un objet de type produit. Dans notre exemple, les produits abstraits sont Window et ScrollBar. - ConcreteProduct (produit concret)
Définit un objet "produit" qui doit être créé par la fabrique concrète correspondante. Dans notre exemple, les produits concrets créés par MotifWidgetFactory sont MotifWindow et MotifScrollBar. Les produits concrets créés par PMWidgetFactory sont PMWindow et PMScrollBar.
Remarque : la demande de construction ne sera pas adressée à MotifWidgetFactory ou à PMWidgetFactory, mais bien à WidgetFactory. - Client
Le client n'utilisera que les interfaces AbstractFactory et AbstractProduct (WidgetFactory et Window ou ScrollBar dans notre exemple).
Collaborations de abstract factory
Normalement, une instance unique de la classe ConcreteFactory est créée à l'exécution. Cette fabrique concrète crée des produits dotés d'une implémentation spécifique. Pour créer des objets produits différents, les clients doivent utiliser une ConcreteFactory différente.
AbstractFactory délègue la création des objets produits à sa sous-classe ConcreteFactory.
Conséquences de abstract factory
Avantages du pattern abstract factory :
Isolation des classes concrètes. Le modèle fabrique abstraite facilite le contrôle des classes d'objets créés par une application. Une fabrique encapsule les actions de prise en charge et de création des objets produits, donc elle isole les clients des classes d'implémentation. Les clients manipulent les instances à travers leurs interfaces abstraites. Les noms des classes produits sont isolés dans l'implémentation de la fabrique concrète; ils n'apparaissent pas dans le code client.
Substitution de familles de produits facilitée. Une classe fabrique concrète n'apparait qu'une seule fois dans une application - précisément, là où elle est instanciée. Il est alors aisé de modifier la fabrique concrète utilisée par cette application. Comme une fabrique abstraite engendre une famille complète de produits, c'est la totalité de la famille de produits qui est remplacée si nous modifions la fabrique abstraite.
Favorise la consistance (maintien de la cohérence) entre les produits. Quand les objets produits d'une famille sont destinés à travailler ensemble, il ets important qu'une application utilise les ojets d'une seule famille à la fois. La classe AbstractFactory facilite le renforcement de cette condition.
Contraintes du pattern abstract factory :
Supporter de nouveaux types de produits est difficile. Etendre la production des fabriques abstraites à de nouveaux produits n'est pas aisé. La cause de cette difficulté est que l'interface AbstractFactory détermine l'ensemble des produits qui peuvent être créés. Supporter de nouveaux types de produits requiert l'extension de l'interface de la fabrique, ce qui implique la modification de la classe AbstractFactory et de toutes ses sous-classes.
Implémentation de abstract factory
Quelques conseils :
Utiliser les fabriques en tant que singletons. Une application ne nécessite qu'une seule instance d'une ConcreteFactory par famille de produits. Il est donc souvent préférable de l'implémenter en Singleton.
Création des produits. AbstractFactory ne fait que déclarer une interface pour la création des produits. C'set aux sous-classes ConcreteProduct de les créer. La façon la plus courante est de définir pour chaque produit une méthode de fabrication. Une ConcreteFactory spécifiera ses produits par un override (surcharge), pour chacun d'eux, de la méthode de fabrication.
Exemples de codes de abstract factory
Code c++ (AbstractFactory Pattern) (81 lignes)
using System; { // MainApp test application class MainApp{ public static void Main(){ // Abstract factory #1 AbstractFactory factory1 = new ConcreteFactory1(); Client c1 = new Client(factory1); c1.Run(); // Abstract factory #2 AbstractFactory factory2 = new ConcreteFactory2(); Client c2 = new Client(factory2); c2.Run(); // Wait for user input Console.Read(); } } // AbstractFactory abstract class AbstractFactory{ public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB(); } // ConcreteFactory1 class ConcreteFactory1: AbstractFactory{ public override AbstractProductA CreateProductA(){ return new ProductA1(); } public override AbstractProductB CreateProductB(){ return new ProductB1(); } } // ConcreteFactory2 class ConcreteFactory2: AbstractFactory{ public override AbstractProductA CreateProductA(){ return new ProductA2(); } public override AbstractProductB CreateProductB(){ return new ProductB2(); } } // AbstractProductA abstract class AbstractProductA{ } // AbstractProductB abstract class AbstractProductB{ public abstract void Interact(AbstractProductA a); } // ProductA1 class ProductA1: AbstractProductA{ } // ProductB1 class ProductB1: AbstractProductB{ public override void Interact(AbstractProductA a){ Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } // ProductA2 class ProductA2: AbstractProductA{ } // ProductB2 class ProductB2: AbstractProductB{ public override void Interact(AbstractProductA a){ Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } // Client class Client{ private AbstractProductA AbstractProductA; private AbstractProductB AbstractProductB; // Constructor public Client(AbstractFactory factory){ AbstractProductB = factory.CreateProductB(); AbstractProductA = factory.CreateProductA(); } public void Run(){ AbstractProductB.Interact(AbstractProductA); } } }
Ce qui produit en sortie :
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
Code Java (AbstractFactory) (74 lignes)
/** * DemoLauncher class for the abstract factory pattern. */ public class DemoLauncher{ AbstractFactory factory1 = new ConcreteFactory1(); Client c1 = new Client(factory1); c1.run(); AbstractFactory factory2 = new ConcreteFactory2(); Client c2 = new Client(factory2); c2.run(); } } /** * Declares an interface for operations that create * abstract product objects. */ public interface AbstractFactory{ AbstractProductA createProductA(); AbstractProductB createProductB(); } /** * Implements the operations to create concrete product objects. */ public class ConcreteFactory1 implements AbstractFactory{ public AbstractProductA createProductA() { return new ProductA1(); }; public AbstractProductB createProductB() { return new ProductB1(); }; } public class ConcreteFactory2 implements AbstractFactory{ public AbstractProductA createProductA() { return new ProductA2(); }; public AbstractProductB createProductB() { return new ProductB2(); }; } /** * Declares an interface for a type of product object. */ public interface AbstractProductA{ } public interface AbstractProductB{ public void interact(AbstractProductA a); } /** * Defines a product object to be created by the corresponsing * concrete factory. Implements the AbstractProduct interface. */ public class ProductA1 implements AbstractProductA{ } public class ProductB1 implements AbstractProductB{ public void interact(AbstractProductA a) { " interacts with "+ a.getClass().getName()); } } public class ProductA2 implements AbstractProductA{ } public class ProductB2 implements AbstractProductB{ public void interact(AbstractProductA a) { " interacts with "+ a.getClass().getName()); } } /** * Client class for the abstract factory pattern. */ public class Client{ private AbstractProductA productA; private AbstractProductB productB; public Client(AbstractFactory factory){ productA = factory.createProductA(); productB = factory.createProductB(); } public void run(){ productB.interact(productA); } }
Patterns apparentés à abstract factory
La classe AbstractFactory est souvent implémentée selon le pattern FactoryMethod, mais elle peut aussi être implémentée en utilisant le pattern Prototype.
Les classes ConcreteFactory sont souvent des Singleton.
Deutsche Übersetzung
Sie haben gebeten, diese Seite auf Deutsch zu besuchen. Momentan ist nur die Oberfläche übersetzt, aber noch nicht der gesamte Inhalt.Wenn Sie mir bei Übersetzungen helfen wollen, ist Ihr Beitrag willkommen. Alles, was Sie tun müssen, ist, sich auf der Website zu registrieren und mir eine Nachricht zu schicken, in der Sie gebeten werden, Sie der Gruppe der Übersetzer hinzuzufügen, die Ihnen die Möglichkeit gibt, die gewünschten Seiten zu übersetzen. Ein Link am Ende jeder übersetzten Seite zeigt an, dass Sie der Übersetzer sind und einen Link zu Ihrem Profil haben.
Vielen Dank im Voraus.
Dokument erstellt 09/10/2005, zuletzt geändert 26/10/2018
Quelle des gedruckten Dokuments:https://www.gaudry.be/de/pattern-abstract-factory.html
Die Infobro ist eine persönliche Seite, deren Inhalt in meiner alleinigen Verantwortung liegt. Der Text ist unter der CreativeCommons-Lizenz (BY-NC-SA) verfügbar. Weitere Informationen auf die Nutzungsbedingungen und dem Autor.