Différences entre le modèle D'usine abstrait et la méthode D'usine
je sais qu'il y a beaucoup de messages sur les différences entre ces deux modèles, mais il y a quelques choses que je ne peux pas trouver.
de 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 cacher la mise en œuvre du client comme ils verront un produit générique. Ma première question concerne l'usine abstraite. C'est son rôle pour vous permettre de créer des familles de béton des objets en (qui peuvent dépendre de l'usine que vous utilisez) plutôt qu'un seul objet en béton? L'usine abstraite ne renvoie-t-elle qu'un très grand objet ou de nombreux objets selon les méthodes que vous appelez?
mes deux dernières questions sont au sujet d'une seule citation que je ne peux pas pleinement comprendre que j'ai vu dans de nombreux endroits:
Une différence entre les deux est que avec le modèle D'usine Abstrait, un délégués de classe la responsabilité de instanciation d'objet à un autre objet par composition alors que L'usine La méthode utilise l'héritage et s'appuie sur une sous-classe pour gérer l' instanciation désirée de l'objet.
ma compréhension est que le modèle de méthode d'usine a une interface Créateur qui fera le créateur de béton être en charge de savoir quel produit concret instantiate. Est-ce que cela signifie en utilisant l'héritage de gérer l'instanciation d'objets?
maintenant, en ce qui concerne cette citation, comment exactement le modèle abstrait d'usine délègue-t-il la responsabilité de l'instanciation de l'objet à un autre objet via la composition? Qu'est-ce que cela signifie? Il semble que le modèle D'usine abstraite utilise également l'héritage pour faire le processus de construction aussi bien à mes yeux, mais encore une fois je suis encore en train d'apprendre au sujet de ces modèles.
toute aide, en particulier pour la dernière question, serait grandement appréciée.
14 réponses
La Différence Entre Les Deux
La principale différence entre une "méthode de fabrique" et un "abstract factory", c'est que la méthode est une méthode unique, et un abrégé de l'usine est un objet. Je pense que beaucoup de gens confondent ces deux termes, et commencent à les utiliser de façon interchangeable. Je me souviens que j'ai eu du mal à trouver exactement la différence quand je les ai appris.
Parce que la méthode est juste une méthode, il peut être redéfinie dans une sous-classe, d'où la deuxième moitié de votre citation:
... la méthode de L'usine utilise héritage et repose sur une sous-classe pour manipuler l'objet désiré instanciation.
La citation suppose qu'un objet appelle sa propre usine méthode ici. Donc la seule chose qui pourrait changer la valeur de retour serait une sous-classe.
L'abstrait l'usine est un objet qui a de multiples méthodes de fabrique. En regardant la première moitié de votre citation:
... avec le modèle D'usine Abstrait, une classe délègue la responsabilité de l'objet instanciation vers un autre objet via composition. ..
ce qu'ils disent c'est qu'il y a un objet A, qui veut faire un objet Foo. Au lieu de faire L'objet Foo lui-même (par exemple, avec une méthode d'usine), il va obtenez un objet différent (l'usine abstraite) pour créer L'objet Foo.
Exemples De Codes
pour vous montrer la différence, voici une méthode d'usine en usage:
class A {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
protected Foo makeFoo() {
return new RegularFoo();
}
}
class B extends A {
protected Foo makeFoo() {
//subclass is overriding the factory method
//to return something different
return new SpecialFoo();
}
}
et voici une usine abstraite en usage:
class A {
private Factory factory;
public A(Factory factory) {
this.factory = factory;
}
public void doSomething() {
//The concrete class of "f" depends on the concrete class
//of the factory passed into the constructor. If you provide a
//different factory, you get a different Foo object.
Foo f = factory.makeFoo();
f.whatever();
}
}
interface Factory {
Foo makeFoo();
Bar makeBar();
Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}
//need to make concrete factories that implement the "Factory" interface here
Abstract factory crée une classe de base avec des méthodes abstraites définissant les méthodes pour les objets qui doivent être créés. Chaque classe d'usine qui dérive la classe de base peut créer leur propre implémentation de chaque type d'objet.
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 La classe Order
a une méthode appelée CreateOrderLine
)
Abstract factory
dans l'exemple ci-dessous, nous concevons une interface afin de pouvoir découpler la création de file d'attente d'un système de messagerie et donc créer des implémentations pour différents systèmes de file d'attente sans avoir à changer la base de code.
interface IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name);
IMessageQueue CreateReplyQueue(string name);
}
public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name)
{
//init queue
return new AzureMessageQueue(/*....*/);
}
IMessageQueue CreateReplyQueue(string name)
{
//init response queue
return new AzureResponseMessageQueue(/*....*/);
}
}
public class MsmqFactory : IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name)
{
//init queue
return new MsmqMessageQueue(/*....*/);
}
IMessageQueue CreateReplyQueue(string name)
{
//init response queue
return new MsmqResponseMessageQueue(/*....*/);
}
}
méthode en usine
le problème dans les serveurs HTTP, Nous avons toujours besoin d'une réponse pour chaque requête.
public interface IHttpRequest
{
// .. all other methods ..
IHttpResponse CreateResponse(int httpStatusCode);
}
sans la méthode factory, les utilisateurs du serveur HTTP (c'est-à-dire les programmeurs) seraient forcés d'utiliser des classes spécifiques d'implémentation qui vont à l'encontre du but de l'interface IHttpRequest
.
par conséquent, nous introduisons la méthode de l'usine de sorte que la création de la classe de réponse est également abstraite.
résumé
le la différence est que le usage prévu de la classe contenant une méthode d'usine n'est pas de créer des objets , tandis qu'une usine abstraite ne devrait être utilisée pour créer des objets.
il faut faire attention en utilisant des méthodes d'usine car il est facile de casser le LSP ( Liskovs principe de Substitution ) lors de la création d'objets.
la différence entre les modèles AbstractFactory et Factory design est la suivante:
"- méthode D'usine est utilisé pour créer un produit seulement, mais usine abstraite est sur la création de familles de produits liés ou dépendants.
- Factory Method pattern expose une méthode au client pour créer l'objet tandis que dans le cas de Abstract Factory ils exposent une famille d'objets connexes qui peuvent consister en ces méthodes D'usine.
- Factory Method pattern cache la construction d'un objet unique où comme Abstract factory method cache la construction d'une famille d'objets liés. Les usines abstraites sont généralement mises en œuvre en utilisant (un ensemble de) méthodes d'usine.
- AbstractFactory pattern utilise la composition pour déléguer la responsabilité de créer un objet à une autre classe tandis que Factory design pattern utilise l'héritage et s'appuie sur la classe dérivée ou la sous-classe pour créer l'objet.
- l'idée derrière la méthode D'usine modèle est qu'il permet le cas où un client ne sait pas quelles classes concrètes il sera nécessaire de créer à l'exécution, mais veut juste obtenir une classe qui fera le emploi alors que AbstractFactory modèle est mieux utilisé lorsque votre système doit créer plusieurs familles de produits ou vous voulez fournir une bibliothèque de produits sans exposer les détails de la mise en œuvre.!
Mise En Œuvre De La Méthode En Usine:
AbstractFactory Modèle De Mise En Œuvre:
Abstract Factory est une interface pour créer des produits connexes, mais la méthode Factory n'est qu'une méthode. Abstract Factory peut être implémenté par plusieurs méthodes D'usine.
considérez cet exemple pour une compréhension facile.
que fournissent les entreprises de télécommunications? Large bande, ligne téléphonique et mobile par exemple, et on vous demande de créer une application pour offrir leurs produits à leurs clients.
en général, ce que vous feriez ici, c'est créer les produits I. le haut débit, la ligne téléphonique et mobile est à travers votre méthode D'usine où vous savez quoi les propriétés que vous avez pour ces produits et son assez droit en avant.
maintenant, la société veut offrir à son client un paquet de leurs produits I. e large bande, ligne téléphonique et mobile Tous ensemble, et voici le Abstract Factory à jouer.
Abstract Factory est en d'autres mots sont de la composition des autres usines qui sont responsables de la création de leurs propres produits et la Abstrait L'usine sait comment placer ces produits dans plus de sens en ce qui concerne ses propres responsabilités.
dans ce cas, BundleFactory
est L'usine abstraite, BroadbandFactory
, PhonelineFactory
et MobileFactory
sont les Factory
. Plus simplement, ces usines auront méthode D'usine pour initialiser les produits individuels.
Se exemple de code ci-dessous:
public class BroadbandFactory : IFactory {
public static Broadband CreateStandardInstance() {
// broadband product creation logic goes here
}
}
public class PhonelineFactory : IFactory {
public static Phoneline CreateStandardInstance() {
// phoneline product creation logic goes here
}
}
public class MobileFactory : IFactory {
public static Mobile CreateStandardInstance() {
// mobile product creation logic goes here
}
}
public class BundleFactory : IAbstractFactory {
public static Bundle CreateBundle() {
broadband = BroadbandFactory.CreateStandardInstance();
phoneline = PhonelineFactory.CreateStandardInstance();
mobile = MobileFactory.CreateStandardInstance();
applySomeDiscountOrWhatever(broadband, phoneline, mobile);
}
private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
// some logic here
}
}
la principale différence entre la méthode D'usine abstraite et la méthode D'usine est que usine abstraite est mis en œuvre par la Composition ; mais méthode D'usine est mis en œuvre par héritage .
Oui, vous avez bien lu: la principale différence entre ces deux modèles est l'ancien débat composition vs héritage .
je ne vais pas reproduire les diagrammes UML ici ceux-ci peuvent être trouvés dans de nombreux endroits. Je veux fournir des exemples de code; cependant, parce que je pense que la combinaison des exemples des deux premières réponses dans ce fil de discussion donnera une meilleure démonstration que l'une ou l'autre réponse seule. De plus, j'ai ajouté la terminologie utilisée dans le livre (GoF) aux noms de classe et de méthode.
Abstract Factory
- le point le plus important à saisir ici est que l'abstrait usine est injecté dans le client. C'est pourquoi nous disons que l'Abstrait Usine est mis en œuvre par Composition. Souvent, une injection de dépendance cadre permettrait de s'acquitter de cette tâche; mais un cadre n'est pas nécessaire pour DI.
- le deuxième point critique est que les usines de béton ici sont pas implémentations de méthode D'usine! Exemple de code pour L'usine La méthode indiquée ci-dessous.
- et enfin, le troisième point à noter est la relation entre la produits: dans ce cas, les sortants et les files d'attente de réponse. Un béton l'usine produit des files D'attente D'Azur, les autres MSMQ. Le GEF fait référence à cette relation produit comme une "famille" et il est important d'être conscient que la famille dans ce cas ne signifie pas la hiérarchie de classe.
public class Client {
private final AbstractFactory_MessageQueue factory;
public Client(AbstractFactory_MessageQueue factory) {
// The factory creates message queues either for Azure or MSMQ.
// The client does not know which technology is used.
this.factory = factory;
}
public void sendMessage() {
//The client doesn't know whether the OutboundQueue is Azure or MSMQ.
OutboundQueue out = factory.createProductA();
out.sendMessage("Hello Abstract Factory!");
}
public String receiveMessage() {
//The client doesn't know whether the ReplyQueue is Azure or MSMQ.
ReplyQueue in = factory.createProductB();
return in.receiveMessage();
}
}
public interface AbstractFactory_MessageQueue {
OutboundQueue createProductA();
ReplyQueue createProductB();
}
public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
@Override
public OutboundQueue createProductA() {
return new AzureMessageQueue();
}
@Override
public ReplyQueue createProductB() {
return new AzureResponseMessageQueue();
}
}
public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
@Override
public OutboundQueue createProductA() {
return new MsmqMessageQueue();
}
@Override
public ReplyQueue createProductB() {
return new MsmqResponseMessageQueue();
}
}
Méthode En Usine
- le point le plus important à saisir ici est que le
ConcreteCreator
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 Méthode d'usine est mis en œuvre par héritage. - le deuxième point critique est de se rappeler que la méthode D'usine Modèle est rien de plus qu'une spécialisation de la Méthode de Modèle Modèle. Les deux motifs partagent une structure identique. Ils ne diffèrent dans leurs objectifs. Méthode de fabrique est creational (il construire quelque chose) tandis que la méthode de modèle est comportementale (il calcule quelque.)
- Et enfin, le troisième point à noter est que le
Creator
(parent) class invoque son proprefactoryMethod()
. Si on enlèveanOperation()
de la classe parent, ne laissant qu'une seule méthode derrière, il n'est plus la Méthode de motif. En d'autres termes, La méthode d'usine ne peut pas être mise en oeuvre avec moins de deux méthodes dans la classe parent; et l'on doit invoquer l'autre.
public abstract class Creator {
public void anOperation() {
Product p = factoryMethod();
p.whatever();
}
protected abstract Product factoryMethod();
}
public class ConcreteCreator extends Creator {
@Override
protected Product factoryMethod() {
return new ConcreteProduct();
}
}
Misc. & Divers Motifs D'Usine
sachez que bien que les GEF définissent deux modèles D'usine Différents, ce ne sont pas les seuls qui existent. Ils 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 premier livre de dessins de la tête inclut encore un autre modèle qu'ils appellent L'usine Simple.
ne tombez pas dans le piège de supposer que chaque modèle D'usine doit correspondre à l'un des GoF.
disons-le clairement que la plupart du temps dans le code de production, nous utilisons le modèle d'usine abstrait parce que la classe A est programmée avec l'interface B. et a besoin de créer des instances de B. Ainsi A doit avoir un objet d'usine pour produire des instances de B. Ainsi A ne dépend pas d'une instance concrète de B. espérons qu'il aide.
comprendre les différences dans les motivations:
Supposons que vous construisez un outil où vous avez des objets et une mise en œuvre concrète des interrelations des objets. Puisque vous prévoyez des variations dans les objets, vous avez créé une indirecte en assignant la responsabilité de créer des variantes des objets à un autre objet ( nous l'appelons usine abstraite ). Cette abstraction présente des avantages considérables. puisque vous prévoyez des extensions futures nécessitant des variantes de ces objets.
Une autre motivation assez intrigante dans cette ligne de pensée est un cas où tous-ou aucun-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 que nous avons souvent tendance à penser que - tant que les variantes d'un objet suivre un contrat uniforme commun ( interface au sens large ), le code de mise en œuvre concrète ne devrait jamais rompre. Le fait curieux ici est que, ce n'est pas toujours vrai, surtout quand le comportement attendu ne peut pas être modélisé par un contrat de programmation.
Un simple ( empruntant l'idée de GoF ) est toutes les applications GUI disent un moniteur virtuel qui émule look-an-feel DE MS ou Mac ou Fedora OS. Ici, par exemple, quand tous les objets widget tels que Fenêtre, bouton, etc. ont variante de MS sauf une barre de défilement qui est dérivé de variante MAC, le but de l'outil échoue mal.
Ces cas ci-dessus constituent le besoin fondamental de Abstract Factory Pattern .
D'un autre côté, imaginez que vous écrivez un cadre de sorte que beaucoup de gens peuvent construire divers outils ( tel que celui dans les exemples ci-dessus ) en utilisant votre Framework. Par l'idée même d'un cadre, vous n'en avez pas besoin, bien que vous ne puissiez pas utiliser des objets concrets dans votre logique. Vous mettez plutôt quelques contrats de haut niveau entre divers objets et la façon dont ils interagissent. Alors que vous ( comme un développeur de cadre ) restez à un niveau très abstrait, chaque constructeur de l'outil est forcé de suivre vos constructions de cadre. Cependant, ils ( l'outil constructeurs ) ont la liberté de décider quel objet à être construit et comment tous les objets qu'ils créent va interagir. À la différence du cas précédent ( du modèle abstrait D'usine ), vous ( en tant que créateur de cadre ) n'avez pas besoin de travailler avec des objets concrets dans ce cas; et peut plutôt rester au niveau du contrat des objets. En outre, contrairement à la deuxième partie des motivations précédentes, vous ou les outilleurs n'avez jamais les 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 même du cas ) à l'utilisation de ses propres objets. Les créations d'objets dans ce cas sont déléguées à chaque exécuteur et les fournisseurs de framework fournissent juste des méthodes uniformes pour créer et retourner des objets. De telles méthodes sont inévitables pour le développeur de cadre de procéder avec leur code et a un nom spécial appelé méthode D'usine ( modèle de méthode D'usine pour le modèle sous-jacent ).
Quelques Notes:
- si vous êtes familier avec la "méthode de modèle", alors vous verriez que les méthodes d'usine sont souvent invoquées à partir des méthodes de modèle dans le cas de programmes se rapportant à n'importe quelle forme de cadre. En revanche, les méthodes de modèle d'application-programmes sont souvent simple mise en œuvre de l'algorithme spécifique et sans usine-méthodes.
- en outre, pour l'exhaustivité des pensées, en utilisant le cadre ( mentionné ci-dessus ), lorsqu'un outilleur construit un outil, à l'intérieur de chaque méthode d'usine, au lieu de créer un objet en béton, il/elle peut déléguer la responsabilité à un objet abstrait-usine, à condition que l'outilleur prévoit des variations des objets en béton pour des extensions futures.
Code Échantillon:
//Part of framework-code
BoardGame {
Board createBoard() //factory method. Default implementation can be provided as well
Piece createPiece() //factory method
startGame(){ //template method
Board borad = createBoard()
Piece piece = createPiece()
initState(board, piece)
}
}
//Part of Tool-builder code
Ludo inherits BoardGame {
Board createBoard(){ //overriding of factory method
//Option A: return new LudoBoard() //Lodu knows object creation
//Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
}
….
}
//Part of Tool-builder code
Chess inherits BoardGame {
Board createBoard(){ //overriding of factory method
//return a Chess board
}
….
}
- ma première question concerne l'usine abstraite. C'est son rôle pour vous permettre de créer des familles d'objets concrets (qui peut dépendre des usines de vous utilisez) plutôt que juste un seul objet concret?
Oui. L'intention de Abstract Factory est:
fournit une interface pour créer des familles d'objets liés ou dépendants sans préciser leurs classes concrètes.
- L'usine abstraite ne renvoie-t-elle qu'un objet très grand ou plusieurs objets selon les méthodes que vous appelez?
idéalement, il devrait retourner un objet par la méthode que le client invoque.
- Ma compréhension est que le factory method pattern a une interface de créateur qui fera le ConcreteCreator être en charge de savoir quel ConcreteProduct instantiate. Est-ce que cela signifie en utilisant l'héritage de gérer l'instanciation d'objets?
Oui. Usine méthode utilise l'héritage.
- Abstract Factory modèle de déléguer la responsabilité de l'instanciation d'objet à un autre objet via composition? Qu'est-ce que cela signifie?
AbstractFactory définit une méthode factorielle et Concretfactory est responsable de la construction D'un produit concret. Il suffit de suivre l'exemple de code dans ce article .
vous pouvez trouver plus de détails dans les messages se connexes:
Quelle est la différence fondamentale entre L'usine et L'usine abstraite Les modèles?
Modèles de Conception: l'Usine de vs méthode de Fabrique vs Abstract Factory
, il est très simple avec un minimum d'interface et concentrez "//1":
class FactoryProgram
{
static void Main()
{
object myType = Program.MyFactory("byte");
Console.WriteLine(myType.GetType().Name);
myType = Program.MyFactory("float"); //3
Console.WriteLine(myType.GetType().Name);
Console.ReadKey();
}
static object MyFactory(string typeName)
{
object desiredType = null; //1
switch (typeName)
{
case "byte": desiredType = new System.Byte(); break; //2
case "long": desiredType = new System.Int64(); break;
case "float": desiredType = new System.Single(); break;
default: throw new System.NotImplementedException();
}
return desiredType;
}
}
points importants: 1. Les mécanismes d'usine & AbstractFactory doivent utiliser l'héritage (système.Objet-> byte, char ...); donc si vous avez l'héritage dans le programme alors L'usine (usine abstraite ne serait pas là très probablement) est déjà là par la conception 2. Creator (MyFactory) connaît le type de béton donc retourne l'objet de type de béton à l'appelant (Main); dans l'abstrait retour usine type serait une Interface.
interface IVehicle { string VehicleName { get; set; } }
interface IVehicleFactory
{
IVehicle CreateSingleVehicle(string vehicleType);
}
class HondaFactory : IVehicleFactory
{
public IVehicle CreateSingleVehicle(string vehicleType)
{
switch (vehicleType)
{
case "Sports": return new SportsBike();
case "Regular":return new RegularBike();
default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
}
}
}
class HeroFactory : IVehicleFactory
{
public IVehicle CreateSingleVehicle(string vehicleType)
{
switch (vehicleType)
{
case "Sports": return new SportsBike();
case "Scooty": return new Scooty();
case "DarkHorse":return new DarkHorseBike();
default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
}
}
}
class RegularBike : IVehicle { public string VehicleName { get { return "Regular Bike- Name"; } set { VehicleName = value; } } }
class SportsBike : IVehicle { public string VehicleName { get { return "Sports Bike- Name"; } set { VehicleName = value; } } }
class RegularScooter : IVehicle { public string VehicleName { get { return "Regular Scooter- Name"; } set { VehicleName = value; } } }
class Scooty : IVehicle { public string VehicleName { get { return "Scooty- Name"; } set { VehicleName = value; } } }
class DarkHorseBike : IVehicle { public string VehicleName { get { return "DarkHorse Bike- Name"; } set { VehicleName = value; } } }
class Program
{
static void Main(string[] args)
{
IVehicleFactory honda = new HondaFactory(); //1
RegularBike hondaRegularBike = (RegularBike)honda.CreateSingleVehicle("Regular"); //2
SportsBike hondaSportsBike = (SportsBike)honda.CreateSingleVehicle("Sports");
Console.WriteLine("******* Honda **********"+hondaRegularBike.VehicleName+ hondaSportsBike.VehicleName);
IVehicleFactory hero = new HeroFactory();
DarkHorseBike heroDarkHorseBike = (DarkHorseBike)hero.CreateSingleVehicle("DarkHorse");
SportsBike heroSportsBike = (SportsBike)hero.CreateSingleVehicle("Sports");
Scooty heroScooty = (Scooty)hero.CreateSingleVehicle("Scooty");
Console.WriteLine("******* Hero **********"+heroDarkHorseBike.VehicleName + heroScooty.VehicleName+ heroSportsBike.VehicleName);
Console.ReadKey();
}
}
points importants: 1. Exigence: Honda créerait "régulier", "sport", mais Hero créerait "DarkHorse", "sport"et " Scooty". 2. pourquoi deux interfaces? Une pour le type de fabricant (IVehicleFactory) et une autre pour l'usine de produit(IVehicle); une autre façon de comprendre 2 interfaces est abstract factory est tout au sujet de la création d'objets connexes 2. Le piège est le retour des enfants D'IVehicleFactory et IVehicle(au lieu de béton en usine); donc j'obtiens la variable parent (IVehicle); puis je crée le type concret réel en appelant CreateSingleVehicle et puis je jette l'objet parent à l'objet enfant réel. Que se passerait-il si je faisais RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; vous obtiendriez ApplicationException et c'est pourquoi nous avons besoin de generic abstract factory que je vous expliquerais si nécessaire. Espérons qu'il aide du débutant au public intermédiaire.
Usine
Imaginez que vous construisez une maison et que vous vous approchez d'un charpentier pour une porte. Vous donnez la mesure pour la porte et vos exigences, et il construira une porte pour vous. Dans ce cas, le charpentier est une usine de portes. Vos spécifications sont entrées pour l'usine, et la porte est la sortie ou le produit de l'usine.
Usine Abstraite
maintenant, considérez le même exemple de la porte. Vous pouvez aller à un charpentier, ou vous pouvez aller à un magasin de portes en plastique ou un magasin de PVC. Toutes sont des usines de portes. En fonction de la situation, vous décidez du type d'usine que vous devez approcher. C'est comme un Résumé de l'Usine.
j'ai expliqué ici à la fois le modèle de méthode D'usine et le modèle d'usine abstraite en commençant par ne pas les utiliser en expliquant les problèmes et en résolvant ensuite les problèmes en utilisant le ci-dessus modèle https://github.com/vikramnagineni/Design-Patterns/tree/master
je préférerais L'usine abstraite à la méthode D'usine à tout moment. De L'exemple de Tom Dalling (grande explication btw) ci-dessus, nous pouvons voir que L'usine abstraite est plus composable en ce que tout ce que nous avons à faire est de passer une usine différente au constructeur (injection de dépendance du constructeur en usage ici). Mais la méthode de L'usine exige que nous introduisions une nouvelle classe (plus de choses à gérer) et que nous utilisions le sous-classement. Toujours préférer la composition à l'héritage.
permettez-moi de le dire précisément. la plupart des réponses ont déjà expliqué, à condition de schémas et d'exemples. donc mon anwer ne serait qu'un paquebot. mes propres mots: - "abstract factory modèle ajoute sur la couche abstraite sur plusieurs méthode de fabrique des implémentations. moyens abstract factory contient ou composite un ou plus d'une méthode de fabrique, modèles de"
un grand nombre des réponses ci-dessus ne fournissent pas de comparaisons de codes entre la méthode abstraite de L'usine et la méthode de L'usine. Voici ma tentative de l'expliquer par Java. J'espère que ça aidera quelqu'un qui a besoin d'une explication simple.
comme GoF le dit à juste titre : Abstract Factory fournit une interface pour créer des familles d'objets liés ou dépendants sans spécifier leurs cours de béton.
public class Client {
public static void main(String[] args) {
ZooFactory zooFactory = new HerbivoreZooFactory();
Animal animal1 = zooFactory.animal1();
Animal animal2 = zooFactory.animal2();
animal1.sound();
animal2.sound();
System.out.println();
AnimalFactory animalFactory = new CowAnimalFactory();
Animal animal = animalFactory.createAnimal();
animal.sound();
}
}
public interface Animal {
public void sound();
}
public class Cow implements Animal {
@Override
public void sound() {
System.out.println("Cow moos");
}
}
public class Deer implements Animal {
@Override
public void sound() {
System.out.println("Deer grunts");
}
}
public class Hyena implements Animal {
@Override
public void sound() {
System.out.println("Hyena.java");
}
}
public class Lion implements Animal {
@Override
public void sound() {
System.out.println("Lion roars");
}
}
public interface ZooFactory {
Animal animal1();
Animal animal2();
}
public class CarnivoreZooFactory implements ZooFactory {
@Override
public Animal animal1() {
return new Lion();
}
@Override
public Animal animal2() {
return new Hyena();
}
}
public class HerbivoreZooFactory implements ZooFactory{
@Override
public Animal animal1() {
return new Cow();
}
@Override
public Animal animal2() {
return new Deer();
}
}
public interface AnimalFactory {
public Animal createAnimal();
}
public class CowAnimalFactory implements AnimalFactory{
@Override
public Animal createAnimal() {
return new Cow();
}
}
public class DeerAnimalFactory implements AnimalFactory{
@Override
public Animal createAnimal() {
return new Deer();
}
}
public class HyenaAnimalFactory implements AnimalFactory{
@Override
public Animal createAnimal() {
return new Hyena();
}
}
public class LionAnimalFactory implements AnimalFactory{
@Override
public Animal createAnimal() {
return new Lion();
}
}