Je sais qu'il existe de nombreux articles sur les différences entre ces deux modèles, mais il y a quelques choses que je ne peux pas trouver.
D'après ce que j'ai lu, je vois que le modèle de méthode d'usine vous permet de définir comment créer un seul produit concret mais en masquant l'implémentation au client car il verra un produit générique. Ma première question concerne l'usine abstraite. Son rôle est-il de vous permettre de créer des familles d'objets concrets dans (cela peut dépendre de quelle usine spécifique vous utilisez) plutôt qu'un simple objet concret? L'usine abstraite ne renvoie-t-elle qu'un très grand objet ou plusieurs objets selon les méthodes que vous appelez?
Mes deux dernières questions portent sur une seule citation que je ne comprends pas bien que j'ai vue à de nombreux endroits:
Une différence entre les deux est qu'avec le modèle Abstract Factory, une classe délègue la responsabilité de l'instanciation d'objet à un autre objet via la composition tandis que le modèle Factory Method utilise l'héritage et s'appuie sur une sous-classe pour gérer l'instanciation d'objet souhaitée.
Ma compréhension est que le modèle de méthode d'usine a une interface Creator qui fera que ConcreteCreator sera en charge de savoir quel ConcreteProduct instancier. Est-ce ce que cela signifie en utilisant l'héritage pour gérer l'instanciation d'objets?
En ce qui concerne cette citation, comment le modèle Abstract Factory délègue-t-il exactement la responsabilité de l'instanciation d'objet à un autre objet via la composition? Qu'est-ce que ça veut dire? Il semble que le modèle Abstract Factory utilise également l'héritage pour faire le processus de construction à mes yeux, mais là encore, j'apprends encore ces modèles.
Toute aide, en particulier avec la dernière question, serait grandement appréciée.
Réponses:
La différence entre les deux
La principale différence entre une "méthode d'usine" et une "usine abstraite" est que la méthode d'usine est une méthode unique et qu'une usine abstraite est un objet. Je pense que beaucoup de gens confondent ces deux termes et commencent à les utiliser de manière interchangeable. Je me souviens que j'avais du mal à trouver exactement quelle était la différence quand je les apprenais.
Parce que la méthode d'usine n'est qu'une méthode, elle peut être remplacée dans une sous-classe, d'où la seconde moitié de votre devis:
La citation suppose qu'un objet appelle sa propre méthode d'usine ici. Par conséquent, la seule chose qui pourrait changer la valeur de retour serait une sous-classe.
L'usine abstraite est un objet qui comporte plusieurs méthodes d'usine. En regardant la première moitié de votre devis:
Ce qu'ils disent, c'est qu'il y a un objet A, qui veut faire un objet Foo. Au lieu de créer l'objet Foo lui-même (par exemple, avec une méthode d'usine), il va obtenir un objet différent (l'usine abstraite) pour créer l'objet Foo.
Exemples de code
Pour vous montrer la différence, voici une méthode d'usine utilisée:
Et voici une usine abstraite en cours d'utilisation:
la source
SpecialFoo
pour être plus clair.L'usine abstraite crée une classe de base avec des méthodes abstraites définissant les méthodes des objets à créer. Chaque classe d'usine qui dérive la classe de base peut créer sa propre implémentation de chaque type d'objet.
La méthode d'usine est juste une méthode simple utilisée pour créer des objets dans une classe. Il est généralement ajouté dans la racine agrégée (la
Order
classe a une méthode appeléeCreateOrderLine
)Usine abstraite
Dans l'exemple ci-dessous, nous concevons une interface afin de pouvoir dissocier la création de files d'attente d'un système de messagerie et donc créer des implémentations pour différents systèmes de files d'attente sans avoir à changer la base de code.
Méthode d'usine
Le problème dans les serveurs HTTP est que nous avons toujours besoin d'une réponse pour chaque demande.
Sans la méthode d'usine, les utilisateurs du serveur HTTP (c'est-à-dire les programmeurs) seraient obligés d'utiliser des classes spécifiques à l'implémentation, ce qui irait à l'encontre du but de l'
IHttpRequest
interface.Par conséquent, nous introduisons la méthode d'usine afin que la création de la classe de réponse soit également abstraite.
Sommaire
La différence est que l' objectif de la classe contenant une méthode de fabrique n'est pas de créer des objets , alors qu'une fabrique abstraite ne doit être utilisée que pour créer des objets.
Il faut être prudent lors de l'utilisation des méthodes d'usine car il est facile de casser le LSP ( principe de substitution Liskov ) lors de la création d'objets.
la source
Button()
pour faire une «famille de produits connexes». Par exemple, l'exemple canonique GoF créeScrollBar()
etWindow()
. L'avantage est que Abstract Factory peut appliquer un thème commun à ses multiples produits.Les différences entre les modèles de conception AbstractFactory et Factory sont les suivantes:
Implémentation du modèle de méthode d'usine:
Mise en œuvre du modèle d'usine abstraite:
la source
La principale différence entre Abstract Factory et Factory Method est que Abstract Factory est implémenté par Composition ; mais la méthode d'usine est implémentée par l'héritage .
Oui, vous avez bien lu: la principale différence entre ces deux modèles est l'ancien débat entre composition et héritage .
Les diagrammes UML se trouvent dans le livre (GoF). Je veux fournir des exemples de code, car je pense que la combinaison des exemples des deux premières réponses dans ce fil donnera une meilleure démonstration que l'une ou l'autre réponse seule. De plus, j'ai utilisé la terminologie du livre dans les noms de classe et de méthode.
Usine abstraite
Méthode d'usine
ConcreteCreator
c'est le client. En d'autres termes, le client est une sous-classe dont le parent définit lefactoryMethod()
. C'est pourquoi nous disons que la méthode Factory est implémentée par héritage.Creator
classe (parent) invoque la siennefactoryMethod()
. Si nous supprimonsanOperation()
de la classe parent, ne laissant qu'une seule méthode derrière, ce n'est plus le modèle de méthode d'usine. En d'autres termes, la méthode Factory ne peut pas être implémentée avec moins de deux méthodes dans la classe parente; et l'un doit invoquer l'autre.Divers & Modèles d'usine divers
Sachez que bien que le GoF définisse deux modèles Factory différents, ce ne sont pas les seuls modèles Factory existants. Ce ne sont même pas nécessairement les modèles d'usine les plus couramment utilisés. Un troisième exemple célèbre est le modèle d'usine statique de Josh Bloch de Java efficace. Le livre Head First Design Patterns comprend un autre modèle qu'ils appellent Simple Factory.
Ne tombez pas dans le piège de supposer que chaque modèle Factory doit correspondre à celui du GoF.
la source
factoryMethod()
toujours êtreprotected
dans le modèle "Méthode d'usine"? (Je pense que oui)public
méthodes d'usine, et la méthode n'a même pas besoin d'êtreabstract
; mais le point critique est que la méthode est destinée à l'héritage, elle ne peut donc pas (par exemple) être soitstatic
oufinal
. J'ai fait la méthodeprotected
etabstract
ici pour mettre en évidence l'extensibilité (requise).Abstract Factory est une interface pour créer des produits associés, mais Factory Method n'est qu'une méthode. Abstract Factory peut être implémenté par plusieurs méthodes d'usine.
la source
Considérez cet exemple pour une compréhension facile.
Que proposent les entreprises de télécommunications? Haut débit, ligne téléphonique et mobile par exemple et on vous demande de créer une application pour proposer leurs produits à leurs clients.
Généralement, ce que vous feriez ici, c'est que la création des produits, c'est-à-dire le haut débit, la ligne téléphonique et le mobile, se fait via votre méthode d'usine où vous savez quelles propriétés vous avez pour ces produits et c'est assez simple.
Maintenant, la société veut offrir à ses clients un ensemble de leurs produits, à savoir le haut débit, la ligne téléphonique et le mobile, et voici la Abstract Factory à jouer.
En d'autres termes, Abstract Factory est la composition d'autres usines qui sont responsables de la création de leurs propres produits et Abstract Factory sait comment mettre ces produits en valeur par rapport à ses propres responsabilités.
Dans ce cas, le
BundleFactory
est l'usine abstraiteBroadbandFactory
,PhonelineFactory
etMobileFactory
sont lesFactory
. Pour simplifier davantage, ces usines auront une méthode d'usine pour initialiser les produits individuels.Consultez l'exemple de code ci-dessous:
J'espère que cela t'aides.
la source
static
méthode dans les deux modèles d'usine GoF. C'est faux.Exemple réel. (Facile à retenir)
Usine
Imaginez que vous construisez une maison et que vous vous approchez d'un charpentier pour une porte. Vous donnez la mesure de la porte et vos besoins, et il construira une porte pour vous. Dans ce cas, le menuisier est une usine de portes. Vos spécifications sont des entrées pour l'usine et la porte est la sortie ou le produit de l'usine.
Usine abstraite
Maintenant, considérons le même exemple de la porte. Vous pouvez vous rendre chez un menuisier, ou vous pouvez vous rendre dans un magasin de portes en plastique ou un magasin de PVC. Tous sont des usines de porte. En fonction de la situation, vous décidez quel type d'usine vous devez approcher. C'est comme une usine abstraite.
J'ai expliqué ici à la fois le modèle de méthode d'usine et le modèle d'usine abstrait en commençant par ne pas les utiliser en expliquant les problèmes, puis en résolvant les problèmes en utilisant les modèles ci-dessus https://github.com/vikramnagineni/Design-Patterns/tree/master
la source
Disons clairement que la plupart du temps dans le code de production, nous utilisons un modèle d'usine abstrait parce que la classe A est programmée avec l'interface B. Et A doit créer des instances de B. Donc, A doit avoir un objet d'usine pour produire des instances de B Donc, A ne dépend d'aucune instance concrète de B. J'espère que cela aide.
la source
Comprendre les différences de motivations:
Supposons que vous construisez un outil où vous avez des objets et une implémentation concrète des interrelations des objets. Puisque vous prévoyez des variations dans les objets, vous avez créé une indirection en assignant la responsabilité de créer des variantes des objets à un autre objet ( nous l'appelons usine abstraite ). Cette abstraction trouve un avantage important car vous prévoyez de futures extensions nécessitant des variantes de ces objets.
Une autre motivation assez intrigante dans cette ligne de pensée est un cas où tout ou partie des objets de l'ensemble du groupe auront une variante correspondante. En fonction de certaines conditions, l'une ou l'autre des variantes sera utilisée et dans chaque cas, tous les objets doivent être de la même variante. Cela peut être un peu contre-intuitif à comprendre car nous avons souvent tendance à penser que - tant que les variantes d'un objet suivent un contrat uniforme commun ( interface au sens large) ), le code d'implémentation concret ne doit jamais se casser. Le fait fascinant ici est que, ce n'est pas toujours le cas, en particulier lorsque le comportement attendu ne peut pas être modélisé par un contrat de programmation.
Un simple ( emprunt de l'idée au GoF ) est toute application graphique, par exemple un moniteur virtuel qui émule l'apparence de MS ou Mac ou Fedora OS. Ici, par exemple, lorsque tous les objets widget tels que fenêtre, bouton, etc. ont une variante MS à l'exception d'une barre de défilement dérivée de la variante MAC, le but de l'outil échoue gravement.
Ces cas ci-dessus forment le besoin fondamental de Abstract Factory Pattern .
D'un autre côté, imaginez que vous écrivez un framework afin que de nombreuses personnes puissent construire différents outils ( comme celui des exemples ci-dessus ) en utilisant votre framework. Par l'idée même d'un framework, vous n'en avez pas besoin, bien que vous ne puissiez pas utiliser des objets concrets dans votre logique. Vous mettez plutôt des contrats de haut niveau entre divers objets et comment ils interagissent. Alors que vous (en tant que développeur de framework ) restez à un niveau très abstrait, chaque constructeur de l'outil est obligé de suivre vos constructions de framework. Cependant, ils ( les constructeurs d'outils ) ont la liberté de décider quel objet à construire et comment tous les objets qu'ils créent interagiront. Contrairement au cas précédent ( de Abstract Factory Pattern ), vous (en tant que créateur de framework) n'ont pas besoin de travailler avec des objets concrets dans ce cas; et peut plutôt rester au niveau du contrat des objets. De plus, contrairement à la deuxième partie des motivations précédentes, vous ou les constructeurs d'outils n'avez jamais de situations de mélange d'objets de variantes. Ici, alors que le code cadre reste au niveau du contrat, chaque constructeur d'outils est limité ( par la nature du cas lui-même ) à utiliser ses propres objets. Les créations d'objets dans ce cas sont déléguées à chaque implémenteur et les fournisseurs de framework fournissent simplement des méthodes uniformes pour créer et renvoyer des objets. De telles méthodes sont inévitables pour le développeur de framework pour continuer avec leur code et ont un nom spécial appelé méthode Factory ( Factory Method Pattern pour le modèle sous-jacent ).
Quelques notes:
Exemple de code:
la source
Oui. L'intention de Abstract Factory est:
Idéalement, il devrait renvoyer un objet par la méthode que le client invoque.
Oui. La méthode d'usine utilise l'héritage.
AbstractFactory définit une FactoryMethod et ConcreteFactory est responsable de la construction d'un ConcreteProduct. Suivez simplement l'exemple de code dans cet article .
Vous pouvez trouver plus de détails dans les articles SE associés:
Quelle est la différence fondamentale entre les motifs d'usine et les motifs d'usine abstraits?
Modèles de conception: méthode Factory vs Factory vs Abstract Factory
la source
La méthode Factory repose sur l'héritage: la création d'objets est déléguée à des sous-classes, qui implémentent la méthode Factory pour créer des objets.
Abstract Factory s'appuie sur la composition des objets: la création d'objets est implémentée dans des méthodes exposées dans l'interface d'usine.
Diagramme de haut niveau du modèle d'usine et d'usine abstraite,
Pour plus d'informations sur la méthode Factory, consultez cet article .
Pour plus d'informations sur la méthode de fabrique abstraite, consultez cet article .
la source
Pour le rendre très simple avec une interface minimale et veuillez concentrer "// 1":
Voici les points importants: 1. Les mécanismes Factory & AbstractFactory doivent utiliser l'héritage (System.Object-> byte, float ...); Donc, si vous avez un héritage dans le programme, Factory (Abstract Factory ne serait probablement pas là) est déjà là par conception 2. Le créateur (MyFactory) connaît le type concret et renvoie donc l'objet de type concret à l'appelant (Main); En résumé, le type de retour d'usine serait une interface.
Points importants: 1. Exigence: Honda créerait "Regular", "Sports" mais Hero créerait "DarkHorse", "Sports" et "Scooty". 2. pourquoi deux interfaces? Un pour le type de fabricant (IVehicleFactory) et un autre pour l'usine de produits (IVehicle); l'autre manière de comprendre 2 interfaces est l'usine abstraite est tout au sujet de créer des objets liés 2. Le hic est le retour des enfants de l'IVehicleFactory et IVehicle (au lieu du béton en usine); je reçois donc la variable parent (IVehicle); puis je crée un type concret réel en appelant CreateSingleVehicle puis en moulant l'objet parent en objet enfant réel. Que se passerait-il si je le faisais
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; vous obtiendrez ApplicationException et c'est pourquoi nous avons besoin d'une fabrique abstraite générique que j'expliquerais si nécessaire.la source
Abstract Factory : Une usine d'usines; une usine qui regroupe les usines individuelles mais liées / dépendantes sans spécifier leurs classes concrètes. Exemple d'usine abstraite
Factory : il fournit un moyen de déléguer la logique d'instanciation aux classes enfants. Exemple de modèle d'usine
la source
Je préférerais à tout moment Abstract Factory à Factory Method. À partir de l'exemple de Tom Dalling (grande explication btw) ci-dessus, nous pouvons voir que Abstract Factory est plus composable en ce que tout ce que nous devons faire est de passer une autre usine au constructeur (injection de dépendance de constructeur utilisée ici). Mais Factory Method nous oblige à introduire une nouvelle classe (plus de choses à gérer) et à utiliser le sous-classement. Préférez toujours la composition à l'héritage.
la source
permettez-moi de le dire avec précision. la plupart des réponses ont déjà été expliquées et ont également fourni des diagrammes et des exemples. donc ma réponse serait juste un paquebot. mes propres mots: - «le modèle d'usine abstrait ajoute la couche abstraite sur plusieurs implémentations de méthodes d'usine. signifie que l'usine abstraite contient ou composite un ou plusieurs modèles de méthode d'usine »
la source
Un grand nombre des réponses ci-dessus ne fournissent pas de comparaisons de code entre le modèle Abstract Factory et Factory Method. Voici ma tentative de l'expliquer via Java. J'espère que cela aide quelqu'un qui a besoin d'une explication simple.
la source