web-dev-qa-db-fra.com

Différences entre le motif abstrait d'usine et la méthode d'usine

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 constate que le modèle de méthode d'usine vous permet de définir comment créer un produit concret unique tout en masquant l'implémentation du client car celui-ci 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 (cela peut dépendre de l’usine spécifique que vous utilisez) plutôt qu’un seul objet concret? La fabrique abstraite ne renvoie-t-elle qu'un ou plusieurs objets très volumineux selon les méthodes que vous appelez?

Mes deux dernières questions portent sur une seule citation que je ne comprends pas bien avoir vue à de nombreux endroits:

Une différence entre les deux est que avec le motif Abstract Factory, a délégués de classe la responsabilité de Instanciation d'objet vers un autre objet via composition alors que l'usine Le modèle de méthode utilise l'héritage et s'appuie sur une sous-classe pour gérer le fichier instanciation d'objet souhaité.

D'après ce que je comprends, le modèle de méthode factory possède une interface Creator qui permettra à ConcreteCreator de savoir quel ConcreteProduct il faut instancier. Est-ce ce que cela signifie en utilisant l'héritage pour gérer l'instanciation d'objet?

Maintenant, en ce qui concerne cette citation, comment exactement le motif Abstract Factory délègue-t-il la responsabilité de l’instanciation d’objet à un autre objet via la composition? Qu'est-ce que ça veut dire? Il semble que le motif Abstract Factory utilise également l'héritage pour effectuer le processus de construction également à mes yeux, mais là encore, je suis encore en train d'apprendre sur ces motifs.

Toute aide, en particulier pour la dernière question, serait grandement appréciée. 

361
Silverbolt

La différence entre les deux

La principale différence entre une "méthode fabrique" et une "fabrique abstraite" est que la méthode fabrique est une méthode unique et qu'une fabrique 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'ai eu du mal à trouver exactement quelle était la différence lorsque je les ai apprises.

Étant donné 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: 

... le modèle de méthode d'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 méthode factory ici. Par conséquent, la seule chose qui pourrait changer la valeur de retour serait une sous-classe.

La fabrique abstraite est un objet comportant plusieurs méthodes de fabrique. En regardant la première moitié de votre citation:

... avec le motif Abstract Factory, une classe délègue la responsabilité d'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 créer l'objet Foo lui-même (par exemple, avec une méthode de fabrique), il va obtenir un objet different (la fabrique abstraite) pour créer l'objet Foo.

Exemples de code

Pour vous montrer la différence, voici une méthode d'usine utilisée:

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 utilisée:

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
398
Tom Dalling

Fabrique abstraite crée une classe de base avec des méthodes abstraites définissant des méthodes pour les objets à créer. Chaque classe de fabrique qui dérive la classe de base peut créer sa propre implémentation de chaque type d'objet.

enter image description here

La méthode Factory est simplement une méthode simple utilisée pour créer des objets dans une classe. Il est généralement ajouté dans la racine d'agrégat (la classe Order a une méthode appelée CreateOrderLine)

enter image description here

Usine abstraite

Dans l'exemple ci-dessous, nous concevons une interface permettant de découpler la création de la file d'attente d'un système de messagerie et donc de créer des implémentations pour différents systèmes de file d'attente sans avoir à changer de 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 d'usine

Le problème des serveurs HTTP est que nous avons toujours besoin d'une réponse pour chaque demande.

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 obligés d'utiliser des classes spécifiques à l'implémentation, qui vont à l'encontre de l'objectif de l'interface IHttpRequest.

Par conséquent, nous introduisons la méthode factory afin que la création de la classe de réponse soit également abstraite.

Résumé

La différence est que le but recherché de la classe contenant une méthode de fabrique n'est pas de créer des objets, alors qu'une fabrique abstraite ne devrait être utilisée que pour créer des objets.

Soyez prudent lorsque vous utilisez les méthodes d'usine car il est facile de casser le principe de substitution LSP ( Liskov ) lors de la création d'objets.

100
jgauffin

Les différences entre les modèles de conception AbstractFactory et Factory sont les suivantes:

  • Méthode d'usine est utilisé pour créer un seul produit mais Abstract Factory concerne la création de familles de produits liés ou dépendants.
  • Le motif Méthode d'usine expose une méthode au client pour la création de l'objet, alors que, dans le cas de {fabrique abstraite}, il expose une famille d'objets liés pouvant être constitués de ces méthodes Factory.
  • Méthode d'usine pattern masque la construction d'un seul objet alors que méthode de la fabrique abstraite masque 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.
  • Le modèle AbstractFactory utilise la composition pour déléguer la responsabilité de la création d'un objet à une autre classe, tandis que le modèle de conception {Factory} _ utilise l'héritage et repose sur la classe ou la sous-classe dérivée pour créer un objet.
  • L’idée de base du modèle Méthode d’usine est qu’elle autorise le cas où un 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 effectue les tâches suivantes. Il est préférable d'utiliser le motif job while AbstractFactory lorsque votre système doit créer plusieurs familles de produits ou si vous souhaitez fournir une bibliothèque de produits sans exposer les détails de la mise en œuvre.!

Implémentation de modèle de méthode d'usine: Factory Method UML

Implémentation du motif AbstractFactory:

Abstract Factory UML

83

Abstract Factory est une interface pour la création de produits connexes, mais la méthode Factory n'en est qu'une. Abstract Factory peut être implémenté par plusieurs méthodes Factory.

Abstract Factory UML

21
Trying

Considérez cet exemple pour faciliter la compréhension.  

Que proposent les entreprises de télécommunication? Par exemple, large bande, ligne téléphonique et mobile, vous êtes invité à créer une application pour proposer leurs produits à leurs clients.

Généralement, vous créez les produits haut débit, ligne téléphonique et mobile par le biais de votre Méthode Factory où vous connaissez les propriétés que vous avez pour ces produits et c’est assez simple.

Désormais, la société souhaite proposer à ses clients un ensemble de leurs produits, large bande, ligne téléphonique et mobile, et voici le Abstract Factory à jouer.

Abstract Factory , en d’autres termes, est la composition d’autres usines qui sont responsables de la création de leurs propres produits et Abstract Factory sait comment placer ces produits de manière plus significative dans le respect de ses propres responsabilités.

Dans ce cas, la BundleFactory est l'usine abstraite, BroadbandFactory, PhonelineFactory et MobileFactory sont la Factory. Pour simplifier davantage ces usines auront Méthode d’usine pour initialiser les produits individuels.

Voir l'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
        // maybe manange some variables and invoke some other methods/services/etc.
    }
}

J'espère que cela t'aides.

11
Abdul Munim

La principale différence entre Abstract Factory et Factory Method est que Abstract Factory est implémenté par Composition; mais la méthode Factory est implémentée par Inheritance.

Oui, vous avez bien lu: la principale différence entre ces deux modèles est l’ancien composition vs héritage débat.

Les diagrammes UML sont disponibles dans le livre (GoF). Je souhaite fournir des exemples de code, car je pense que la combinaison des exemples des deux premières réponses de ce fil donnera une meilleure démonstration que l’une ou l’autre des réponses. De plus, j'ai utilisé la terminologie du livre dans les noms de classe et de méthode.

Fabrique abstraite

  1. Le point le plus important à saisir ici est que la fabrique abstraite est injectée dans le client. C'est pourquoi nous disons que Abstract Factory est implémenté par Composition. Souvent, un cadre d'injection de dépendance effectue cette tâche; mais un cadre n'est pas nécessaire pour DI.
  2. Le deuxième point critique est que les usines de béton ici sont Pas des implémentations de méthode d’usine! Exemple de code pour Factory La méthode est indiquée plus bas.
  3. Et enfin, le troisième point à noter est la relation entre les produits : Dans ce cas, les files d'attente sortantes et de réponse. Une usine en béton produit des files d'attente Azure, l'autre MSMQ. Le GoF qualifie cette relation de produit de "famille" et il est important de savoir que cette famille ne signifie pas 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 d'usine

  1. Le point le plus important à saisir ici est que la ConcreteCreatorest le client. En d'autres termes, le client est une sous-classe dont le parent définit la factoryMethod(). C'est pourquoi nous disons que Méthode Factory est implémentée par Héritage.
  2. Le deuxième point critique est de rappeler que la méthode d'usine Pattern n'est rien de plus qu'une spécialisation de la méthode de modèle Pattern. Les deux modèles partagent une structure identique. Ils seulement Diffèrent dans le but. La méthode d'usine est creational (elle construit Quelque chose) alors que la méthode de modèle est comportementale (elle calcule Quelque chose).
  3. Enfin, le troisième point à noter est que la classe Creator (parent) Appelle sa propre factoryMethod(). Si nous supprimons anOperation() de la classe parente en ne laissant qu'une seule méthode Derrière, il ne s'agit plus du modèle Factory Method. En d'autres termes, Factory Method ne peut pas être implémenté avec moins de deux méthodes dans La classe parente; et l'un 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. Et divers modèles d'usine

Sachez que, bien que le GoF définisse deux modèles d’usine différents, il ne s’agit pas des seuls modèles d’usine 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 Static Factory de Effective Java de Josh Bloch. Le livre Head First Design Patterns inclut un autre motif appelé Simple Factory.

Ne tombez pas dans le piège de supposer que chaque modèle d’usine doit correspondre à un modèle du GoF.

8
jaco0646

Disons clairement que la plupart du temps, dans le code de production, nous utilisons un modèle d'usine abstrait car 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 usine pour produire des instances de B Donc, A ne dépend d'aucun cas concret de B. J'espère que cela aidera.

3
Adrian Liu

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 attribuant la responsabilité de créer des variantes des objets à un autre objet (nous l'appelons fabrique abstraite). Cette abstraction présente un grand avantage car vous prévoyez des extensions futures nécessitant des variantes de ces objets. 

Une autre motivation plutôt intrigante dans cette ligne de pensée est le cas où tous ou aucun des objets du groupe entier auront une variante correspondante. En fonction de certaines conditions, l’une des variantes sera utilisée et, dans chaque cas, tous les objets doivent appartenir à la même variante. Cela peut sembler 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 casser. Le fait intrigant est que ce n’est pas toujours le cas, en particulier lorsque le comportement attendu ne peut être modélisé par un contrat de programmation. 

Un simple (empruntant l’idée de GoF) est n’importe quelle application à interface graphique, disons un moniteur virtuel qui émule l’aspect de MS, Mac ou de Fedora. Ici, par exemple, lorsque tous les objets de 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, la fonction de l'outil échoue. 

Ces cas ci-dessus constituent le besoin fondamental de Modèle d'usine abstrait .

D'autre part, imaginez que vous écrivez un framework afin que de nombreuses personnes puissent créer divers outils (comme celui des exemples ci-dessus) à l'aide de votre framework. Par l’idée même d’un framework, vous n’avez pas besoin de, bien que vous ne puissiez pas utiliser d’objets concrets dans votre logique. Vous mettez plutôt des contrats de haut niveau entre différents objets et leur interaction. 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 de l'outil) ont la liberté de décider quel objet à construire et comment tous les objets qu'ils créeront interagiront. Contrairement au cas précédent (de Abstract Factory Pattern), vous (en tant que créateur de structure) n'avez 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 ne rencontrez jamais les situations de mélange d’objets à partir de variantes. Ici, tant 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. Dans ce cas, les créations d'objet sont déléguées à chaque implémenteur et les fournisseurs d'infrastructure fournissent simplement des méthodes uniformes pour créer et renvoyer des objets. Ces méthodes sont inévitables pour que les développeurs d'infrastructure utilisent leur code et portent un nom spécial appelé Méthode Factory (Modèle de méthode Factory pour le modèle sous-jacent). 

Quelques notes: 

  • Si vous connaissez la ‘méthode template’, alors vous constaterez que les méthodes fabrique sont souvent appelées à partir de méthodes template dans le cas de programmes appartenant à n’importe quel type de framework. En revanche, les méthodes de modèle des programmes d’application sont souvent une simple implémentation d’algorithme spécifique et dépourvues de méthode d’usine.
  • De plus, pour la complétude des pensées, en utilisant le cadre (mentionné ci-dessus), quand un constructeur d'outil crée un outil, au sein de chaque méthode d'usine, au lieu de créer un objet concret, il/elle peut déléguer la responsabilité à un objet de fabrique abstraite, à condition que le constructeur d’outils prévoie des variations des objets concrets pour de futures extensions.

Exemple de code:

//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
    }
    ….
}
3
KGhatak
  1. Ma première question concerne l'usine abstraite. Son rôle est-il de vous permettre de créer des familles d’objets concrets (cela peut dépendre de l’usine spécifique que vous utilisez) plutôt qu’un seul objet concret? 

Oui. Le but de Abstract Factory est:

Fournissez une interface pour créer des familles d'objets liés ou dépendants sans spécifier leurs classes concrètes.


  1. La fabrique abstraite ne renvoie-t-elle qu'un ou plusieurs objets très volumineux selon les méthodes que vous appelez?

Idéalement, il devrait renvoyer un objet par la méthode invoquée par le client. 

  1. D'après ce que je comprends, le modèle de méthode factory possède une interface Creator qui permettra à ConcreteCreator de savoir quel ConcreteProduct il faut instancier. Est-ce ce que cela signifie en utilisant l'héritage pour gérer l'instanciation d'objet?

Oui. La méthode d'usine utilise l'héritage. 

  1. Abstract Factory Pattern délègue-t-il la responsabilité de l'instanciation d'objet à un autre objet via la composition? Qu'est-ce que ça veut dire?

AbstractFactory définit FactoryMethod et ConcreteFactory est responsable de la construction d'un ConcreteProduct. Suivez l’exemple de code de cet articlearticle .

Vous pouvez trouver plus de détails dans les messages SE connexes:

Quelle est la différence fondamentale entre les modèles Factory et Abstract Factory?

Modèles de conception: Méthode vs usine vs usine abstraite

3
Ravindra babu

Pour simplifier les choses avec un minimum d’interface, veuillez vous concentrer sur "// 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 Factory & AbstractFactory doivent utiliser l'héritage (System.Object-> byte, float ...); donc, si vous avez un héritage dans le programme, alors Factory (Abstract Factory n'y serait probablement pas) est déjà là par conception 2. Le créateur (MyFactory) connaît le type concret et renvoie donc un objet de type concret à l'appelant (Principal); En résumé, le type de retour d'usine 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. Condition préalable: Honda créerait "Régulier", "Sport", mais Hero créerait "DarkHorse", "Sports" et "Scooty". 2. pourquoi deux interfaces? Un pour le type de fabricant (IVehicleFactory) et un autre pour le produit en usine (IVehicle); Une autre façon de comprendre 2 interfaces est l’usine abstraite qui consiste à créer des objets liés. 2. La capture est le retour des enfants de IVehicleFactory et de IVehicle (au lieu de béton dans l’usine); donc je reçois la variable parent (IVehicle); Ensuite, je crée un type concret en appelant CreateSingleVehicle, puis en convertissant l'objet parent en objet enfant réel. Que se passerait-il si je 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 je vous expliquerais si nécessaire. J'espère que cela aide du débutant au public intermédiaire.

2
Saurabh

Exemple de vie réelle. (Facile à retenir)

Usine

Imaginez que vous construisez une maison et que vous vous approchez d'un menuisier 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 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 aller chez un menuisier, ou dans un magasin de portes en plastique ou un magasin de PVC. Tous sont des usines de portes. 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 Factory 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 ci-dessus https://github.com/vikramnagineni/Design-Patterns/tree/master

1

Je préférerais Abstract Factory à Factory Method à tout moment. D'après l'exemple de Tom Dalling (très bonne explication, ci-dessus), nous pouvons voir que Abstract Factory est plus composable en ce sens que tout ce que nous avons à faire est de passer une Factory différente 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 des sous-classes. Préférez toujours la composition à l'héritage. 

0
he9lin

Méthode Factory repose sur l'héritage: la création d'objet est déléguée à des sous-classes, qui implémentent la méthode Factory pour créer des objets.

Abstract Factory _ repose sur la composition d'objet: la création d'objet est implémentée dans les méthodes exposées dans l'interface de fabrique.

Diagramme de haut niveau du modèle d'usine et abstrait,

diagram

Pour plus d'informations sur la méthode Factory, reportez-vous à cet article .

Pour plus d'informations sur la méthode de fabrique abstraite, consultez cet article .

0
user2266614

permettez-moi de le dire précisément. la plupart des réponses ont déjà été expliquées, ainsi que des diagrammes et des exemples. alors ma réponse serait juste un paquebot. Mes propres mots: - «Le modèle de fabrique abstraite ajoute le calque abstrait à plusieurs implémentations de méthodes de fabrique. signifie fabrique abstraite contient ou compose un ou plusieurs modèles de méthode fabrique ”

0
King

Un grand nombre des réponses ci-dessus ne fournissent pas de comparaisons de code entre les motifs Abstract Factory et Factory Method. Voici ma tentative d’explication via Java. J'espère que cela aidera quelqu'un qui a besoin d'une explication simple.

Comme le dit si bien GoF: Abstract Factory fournit une interface pour créer des familles d’objets apparentés ou dépendants sans spécifier leurs classes concrètes.

        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();
            }

        }
0
Jatin Shashoo

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 à des classes enfants. Exemple de modèle d'usine

0
Atul Jain