
Le modèle de conception « fabrication abstraite » en génie logiciel permet de créer des familles d'objets apparentés sans imposer leurs classes concrètes. Il encapsule un groupe de fabriques individuelles partageant un thème commun, sans spécifier leurs classes concrètes. Selon ce modèle, un composant logiciel client crée une implémentation concrète de la fabrique abstraite, puis utilise l' interface générique de cette fabrique pour créer les objets concrets appartenant à la famille. Le client ignore quels objets concrets il reçoit de chacune de ces fabriques internes, car il utilise uniquement les interfaces génériques de leurs produits. Ce modèle sépare les détails d'implémentation d'un ensemble d'objets de leur utilisation générale et repose sur la composition d'objets, la création d'objets étant implémentée dans les méthodes exposées par l'interface de la fabrique.
L'utilisation de ce modèle permet d'interchanger les implémentations concrètes sans modifier le code qui les utilise, même à l'exécution . Cependant, comme pour d'autres modèles de conception similaires, son emploi peut engendrer une complexité inutile et un travail supplémentaire lors de l'écriture initiale du code. De plus, des niveaux de séparation et d'abstraction plus élevés peuvent rendre les systèmes plus difficiles à déboguer et à maintenir.
Design Patterns de 1994. Il peut être utilisé pour résoudre des problèmes tels que :- Comment une application peut-elle être indépendante de la manière dont ses objets sont créés ?
- Comment une classe peut-elle être indépendante de la manière dont les objets dont elle a besoin sont créés ?
- Comment créer des familles d'objets liés ou dépendants ?
Créer des objets directement au sein de la classe qui les requiert est une approche rigide. Elle fige la classe sur des objets spécifiques et empêche toute modification ultérieure de leur instanciation sans modifier la classe elle-même. De plus, elle limite la réutilisabilité de la classe si d'autres objets sont nécessaires et complique son test, car il est impossible de remplacer les objets réels par des objets simulés.
Une fabrique est l'emplacement, dans le code, d'une classe concrète où les objets sont construits . L'implémentation de ce modèle vise à isoler la création des objets de leur utilisation et à créer des familles d'objets apparentés sans dépendre de leurs classes concrètes. Cela permet d' introduire de nouveaux types dérivés sans modifier le code qui utilise la classe de base .
Ce modèle décrit comment résoudre de tels problèmes :
- Encapsuler la création d'objets dans un objet (usine) séparé en définissant et en implémentant une interface pour la création d'objets.
- Déléguez la création d'objets à un objet fabrique au lieu de créer les objets directement.
Cela rend une classe indépendante de la manière dont ses objets sont créés. Une classe peut être configurée avec un objet fabrique, qu'elle utilise pour créer des objets, et cet objet fabrique peut être remplacé à l'exécution.
opérateur `new` ) ou un pointeur de type abstrait vers l'objet concret créé.Cela isole le code client de la création d'objets en demandant aux clients de demander à un objet fabrique de créer un objet du type abstrait souhaité et de renvoyer un pointeur abstrait vers l'objet.
Un exemple est une classe fabrique abstraite DocumentCreatorqui fournit des interfaces pour créer plusieurs produits (par exemple, createLetter()et createResume()). Le système disposerait d'un nombre quelconque de versions concrètes dérivées de cette DocumentCreatorclasse, telles que FancyDocumentCreatorou ModernDocumentCreator, chacune avec une implémentation différente de createLetter()et createResume()qui créerait des objets correspondants tels que FancyLetterou ModernResume. Chaque produit est dérivé d'une classe abstraite simple , telle que Letterou , Resumeconnue du client. Le code client acquerrait une instance appropriée de DocumentCreatoret appellerait ses méthodes de fabrique . Chaque objet résultant serait créé à partir de la même DocumentCreatorimplémentation et partagerait un thème commun. Le client n'aurait besoin de savoir que manipuler la classe abstraite Letterou Resume, et non la version spécifique créée par la fabrique concrète.
Comme la fabrique ne renvoie qu'une référence ou un pointeur vers un type abstrait, le code client qui a demandé l'objet à la fabrique ignore le type concret de l'objet créé et n'en est pas affecté . Cependant, la fabrique abstraite connaît le type d'un objet concret (et donc d'une fabrique concrète). Par exemple, la fabrique peut lire le type de l'objet à partir d'un fichier de configuration. Le client n'a alors pas besoin de spécifier le type, puisqu'il est déjà défini dans le fichier de configuration. Concrètement, cela signifie :
- Le code client ignore tout du type concret et n'a donc pas besoin d'inclure de fichiers d'en-tête ni de déclarations de classes s'y rapportant. Il manipule uniquement le type abstrait. Les objets d'un type concret sont bien créés par la fabrique, mais le code client y accède uniquement via leurs interfaces abstraites .
- L'ajout de nouveaux types concrets s'effectue en modifiant le code client pour utiliser une fabrique différente, une modification qui tient généralement sur une seule ligne dans un seul fichier. Cette fabrique crée alors des objets d'un type concret différent, mais retourne toujours un pointeur du même type abstrait qu'auparavant, préservant ainsi le code client de toute modification. Cette méthode est nettement plus simple que de modifier le code client pour instancier un nouveau type. Cette dernière option nécessiterait de modifier chaque occurrence d'un nouvel objet dans le code, ainsi que de s'assurer que toutes ces occurrences connaissent le nouveau type concret, par exemple en incluant un fichier d'en-tête de classe concrète. Si tous les objets de fabrique sont stockés globalement dans un singleton , et que tout le code client passe par ce singleton pour accéder à la fabrique appropriée pour la création d'objets, alors changer de fabrique est aussi simple que de modifier le singleton.
Structure
Diagramme UML
ClientProductAProductBProductA1ProductB1ClientAbstractFactoryClientFactory1AbstractFactoryProductA1ProductB1Le diagramme de séquence UML illustre les interactions d'exécution. L' objet appelle l' objet, qui crée et renvoie un objet. Ensuite, l'objet appelle à son tour , créant et renvoyant un objet.ClientcreateProductA()Factory1ProductA1ClientcreateProductB()Factory1ProductB1
Variantes
La structure originale du modèle de fabrique abstraite, telle que définie en 1994 dans Design Patterns , repose sur des classes abstraites pour la fabrique abstraite et les produits abstraits à créer. Les fabriques et les produits concrets sont des classes qui spécialisent les classes abstraites par héritage.
Une structure plus récente de ce modèle repose sur des interfaces qui définissent la fabrique abstraite et les produits abstraits à créer. Cette conception utilise la prise en charge native des interfaces ou des protocoles dans les langages de programmation courants afin d'éviter l'héritage. Dans ce cas, les fabriques et les produits concrets sont des classes qui réalisent l'interface en l'implémentant.
Exemple
Cette implémentation C++23 est basée sur l'implémentation pré-C++98 présentée dans le livre.
Le résultat du programme est :
Plus d articles de Worldlex Wiki
Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.
Explorer l index