design-patterns - pattern - factory method




Quelle est la différence fondamentale entre les Factory et Abstract Factory Patterns? (14)

Source pour cette information tirée de: http://java.dzone.com/news/intro-design-patterns-abstract

Usine abstraite et méthode d'usine

Les méthodes d'une fabrique abstraite sont implémentées en tant que méthodes d'usine. Le modèle d'usine abstrait et le modèle de méthode d'usine découplent le système client des classes d'implémentation réelles via les types abstraits et les fabriques. La méthode usine crée des objets via l'héritage, où l'usine abstraite crée des objets via la composition.

Le modèle d'usine abstrait est constitué d'une AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct et Client.

Comment mettre en œuvre

Le modèle d'usine abstrait peut être implémenté en utilisant le modèle de méthode d'usine, le modèle de prototype ou le modèle singleton. L'objet ConcreteFactory peut être implémenté en tant que singleton car une seule instance de l'objet ConcreteFactory est nécessaire.

Le modèle de méthode d'usine est une version simplifiée du motif Usine abstraite. Le modèle de méthode d'usine est responsable de la création de produits appartenant à une même famille, tandis que le modèle Usine abstraite traite plusieurs familles de produits.

Factory Method utilise des interfaces et des classes abstraites pour découpler le client de la classe du générateur et des produits résultants. Abstract Factory dispose d'un générateur qui sert de conteneur pour plusieurs méthodes d'usine, ainsi que d'interfaces découplant le client du générateur et des produits.

Quand utiliser le modèle de méthode d'usine

Utilisez le modèle Factory Method lorsqu'il est nécessaire de découpler un client d'un produit particulier qu'il utilise. Utilisez la méthode usine pour décharger un client de la responsabilité de la création et de la configuration des instances d'un produit.

Quand utiliser le motif d'usine abstrait

Utilisez le modèle Usine abstraite lorsque les clients doivent être découplés des classes de produits. Particulièrement utile pour la configuration et la modification du programme. Le modèle Usine abstraite peut également imposer des contraintes sur les classes qui doivent être utilisées avec d'autres. Il peut être beaucoup de travail pour faire de nouvelles usines concrètes.

Exemples:

Exemple d'usine abstraite 1

Cette spécification pour les disques pour préparer différents types de pâtes dans un fabricant de pâtes est l'usine abstraite, et chaque disque spécifique est une usine. Toutes les usines (disques de fabricants de pâtes) héritent leurs propriétés de l'usine abstraite. Chaque disque individuel contient des informations sur la façon de créer les pâtes, ce qui n'est pas le cas du fabricant de pâtes.

Exemple d'usine abstraite 2:

L'équipement d'estampage correspond à l'usine abstraite, car il s'agit d'une interface pour les opérations qui créent des objets de produit abstraits. Les matrices correspondent à l'usine de béton, car elles créent un produit concret. Chaque catégorie de pièce (capot, porte, etc.) correspond au produit abstrait. Des pièces spécifiques (c.-à-d. La porte côté conducteur pour 99 camry) correspondent aux produits en béton.

Exemple de méthode d'usine:

La compagnie de jouets correspond au créateur, car elle peut utiliser l'usine pour créer des objets de produit. La division de l'entreprise de jouets qui fabrique un type spécifique de jouet (cheval ou voiture) correspond à ConcreteCreator.

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


Le modèle d'usine abstraite

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

  • Le motif Usine abstraite est très similaire au motif Méthode d'usine. Une différence entre les deux est qu'avec le pattern Usine abstraite, une classe délègue la responsabilité de l'instanciation d'objet à un autre objet via la composition alors que le pattern Usine utilise l'héritage et s'appuie sur une sous-classe pour gérer l'instanciation d'objet désirée.

  • En fait, l'objet délégué utilise fréquemment des méthodes d'usine pour effectuer l'instanciation!

Modèle d'usine

  • Les motifs d'usine sont des exemples de motifs de création

  • Les modèles créatifs permettent d'abstraire le processus d'instanciation de l'objet. Ils cachent comment les objets sont créés et contribuent à rendre le système global indépendant de la façon dont ses objets sont créés et composés.

  • Les modèles de création de classe se concentrent sur l'utilisation de l'héritage pour décider de l'objet à instancier Méthode d'usine

  • Les modèles de création d'objets se concentrent sur la délégation de l'instanciation à un autre objet

Référence: Factory vs Abstract Factory


Beaucoup de gens se sentiront peut-être surpris, mais cette question est incorrecte . Si vous entendez cette question pendant une entrevue, vous devez aider l'intervieweur à comprendre où se trouve la confusion.

Commençons par le fait qu'il n'y a pas de motif concret qu'on appelle juste "Usine". Il y a un modèle appelé "Usine abstraite", et il y a un modèle appelé "Méthode d'usine".

Alors, que signifie "Factory" alors? l'un des suivants (tout peut être considéré comme correct, en fonction de la portée de la référence):

  • Certaines personnes l'utilisent comme un alias (raccourci) pour " Abstract Factory ".
  • Certaines personnes l'utilisent comme un alias (raccourci) pour " Factory Method ".
  • Certaines personnes l'utilisent comme un nom plus général pour tous les modèles d'usine / de création. Par exemple, "Usine abstraite" et "Méthode d'usine" sont des usines.

Et, malheureusement , beaucoup de gens utilisent "Factory" pour désigner un autre type d'usine, qui crée des usines ou des usines (ou leurs interfaces). Basé sur leur théorie:

Product implémente IProduct, créé par Factory, qui implémente IFactory, créé par AbstractFactory.

Pour comprendre à quel point c'est stupide, continuons notre équation:

AbstractFactory implémente IAbstractFactory, qui est créé par ... AbstractAbstractFactory ???

J'espère que vous voyez le point. Ne soyez pas confus, et s'il vous plaît n'inventez pas des choses qui n'existent pas pour la raison.

-

PS : Factory for Products est AbstractFactory et Factory for Abstract Factories est également un exemple de AbstractFactory.


Exemple / scénario pour l'usine abstraite

Je vis dans un endroit où il pleut pendant la saison des pluies, de la neige en hiver et du chaud et du soleil en été. J'ai besoin de différents types de vêtements pour me protéger des éléments. Pour ce faire, je vais au magasin près de chez moi et demande des vêtements / articles pour me protéger. Le magasinier me donne l'article approprié selon l'environnement et la profondeur de ma poche. Les articles qu'il me donne sont du même niveau de qualité et de gamme de prix. Comme il est conscient de mes normes, il est facile pour lui de le faire. Mais quand un gars riche de l'autre côté de la rue arrive avec les mêmes exigences, il reçoit un article de marque, cher. Une chose notable est que tous les articles qu'il me donne se complètent en terme de qualité, standard et coût. On peut dire qu'ils vont les uns avec les autres. C'est le cas des objets que ce riche mec reçoit.

Donc, en regardant le scénario ci-dessus, j'apprécie maintenant l'efficacité du magasinier. Je peux remplacer ce commerçant avec un magasin abstrait. Les articles que nous recevons avec des articles abstraits et moi et les riches comme clients en perspective. Tout ce dont nous avons besoin est le produit / article qui correspond à nos besoins.

Maintenant, je peux facilement me voir en considérant un magasin en ligne qui fournit un ensemble de services à ses nombreux clients. Chaque client appartient à l'un des trois groupes. Lorsqu'un utilisateur de groupe premium ouvre le site, il obtient une grande interface utilisateur, un panneau publicitaire hautement personnalisé, plus d'options dans les menus, etc. Ces mêmes fonctionnalités sont présentées à l'utilisateur Gold, mais la fonctionnalité du menu est moindre. et légèrement moins d'interface utilisateur egronomic. Dernier est mon type d'utilisateur, un utilisateur 'groupe gratuit'. Je suis juste assez servi pour que je ne sois pas offensé. L'interface utilisateur est un strict minimum, les publicités sont tellement décalées que je ne sais pas ce qui s'y trouve, enfin le menu est seulement déconnecté.

Si j'ai la chance de construire quelque chose comme ce site, je considérerais certainement Abstract Factory Pattern.

Produits abstraits: Panneau de publicité, Menu, peintre UI.
Usine abstraite: expérience utilisateur Web Store
Concreate Factory: Expérience utilisateur Premium, expérience utilisateur Gold, expérience utilisateur générale.


L'usine abstraite est une interface pour créer des objets liés mais la méthode d'usine est une méthode. L'usine abstraite est implémentée par la méthode d'usine.


La principale différence dans ces usines est quand ce que vous voulez faire avec les usines et quand vous voulez l'utiliser.

Parfois, lorsque vous effectuez une IOC (inversion de contrôle, par exemple une injection de constructeur), vous savez que vous pouvez créer des objets solides. Comme mentionné dans l'exemple ci-dessus de fruits, si vous êtes prêt à créer des objets de fruits, vous pouvez utiliser un modèle d'usine simple.

Mais plusieurs fois, vous ne voulez pas créer d'objets solides, ils viendront plus tard dans le flux du programme. Mais la configuration vous indique le type d'usine que vous voulez utiliser au démarrage, au lieu de créer des objets, vous pouvez transmettre au constructeur des usines dérivées d'une classe de fabrique commune dans IOC.

Donc, je pense que c'est aussi à propos de la vie de l'objet et de la création.


Modèle d'usine: L'usine produit des implémentations IProduct

Abstract Factory Pattern: Une fabrique-usine produit des IFactories, qui à leur tour produit des IProducts :)

[Mise à jour en fonction des commentaires]
Ce que j'ai écrit plus tôt n'est pas correct selon Wikipedia au moins. Une usine abstraite est simplement une interface d'usine. Avec elle, vous pouvez changer vos usines à l'exécution, pour permettre différentes usines dans des contextes différents. Les exemples pourraient être différentes usines pour différents OS'es, fournisseurs de SQL, intergiciels-conducteurs etc.


Par définition, nous pouvons faire glisser les différences de deux:

Factory: Une interface est utilisée pour créer un objet, mais la sous-classe décide de la classe à instancier. La création d'objet est faite quand c'est nécessaire.

Usine abstraite: Usine abstraite modèle agit comme une super-usine qui crée d'autres usines. Dans le modèle Usine abstraite, une interface est responsable de la création d'un ensemble d'objets associés ou d'objets dépendants sans spécifier leurs classes concrètes.

Ainsi, dans les définitions ci-dessus, nous pouvons mettre l'accent sur une différence particulière. c'est-à-dire, le motif d'usine est responsable de la création d'objets et Abstract Factory est responsable de la création d'un ensemble d'objets connexes; évidemment à la fois à travers une interface.

Modèle d'usine:

public interface IFactory{
  void VehicleType(string n);
 }

 public class Scooter : IFactory{
  public void VehicleType(string n){
   Console.WriteLine("Vehicle type: " + n);
  }
 }

 public class Bike : IFactory{
  public void VehicleType(string n) {
  Console.WriteLine("Vehicle type: " + n);
  }
 }

 public interface IVehicleFactory{
  IFactory GetVehicleType(string Vehicle);
 }

 public class ConcreteVehicleFactory : IVehicleFactory{
 public IFactory GetVehicleType(string Vehicle){
   switch (Vehicle){
    case "Scooter":
     return new Scooter();
    case "Bike":
     return new Bike();
    default:
    return new Scooter();
  }
 }

 class Program{
  static void Main(string[] args){
   IVehicleFactory factory = new ConcreteVehicleFactory();
   IFactory scooter = factory.GetVehicleType("Scooter");
   scooter.VehicleType("Scooter");

   IFactory bike = factory.GetVehicleType("Bike");
   bike.VehicleType("Bike");

   Console.ReadKey();
 }
}

Modèle d'usine abstraite:

interface IVehicleFactory{
 IBike GetBike();
 IScooter GetScooter();
}

class HondaFactory : IVehicleFactory{
     public IBike GetBike(){
            return new FZS();
     }
     public IScooter GetScooter(){
            return new FZscooter();
     }
 }
class HeroFactory: IVehicleFactory{
      public IBike GetBike(){
            return new Pulsur();
     }
      public IScooter GetScooter(){
            return new PulsurScooter();
     }
}

interface IBike
    {
        string Name();
    }
interface IScooter
    {
        string Name();
    }

class FZS:IBike{
   public string Name(){
     return "FZS";
   }
}
class Pulsur:IBike{
   public string Name(){
     return "Pulsur";
   }
}

class FZscooter:IScooter {
  public string Name(){
     return "FZscooter";
   }
}

class PulsurScooter:IScooter{
  public string Name(){
     return "PulsurScooter";
   }
}

enum MANUFACTURERS
{
    HONDA,
    HERO
}

class VehicleTypeCheck{
        IBike bike;
        IScooter scooter;
        IVehicleFactory factory;
        MANUFACTURERS manu;

        public VehicleTypeCheck(MANUFACTURERS m){
            manu = m;
        }

        public void CheckProducts()
        {
            switch (manu){
                case MANUFACTURERS.HONDA:
                    factory = new HondaFactory();
                    break;
                case MANUFACTURERS.HERO:
                    factory = new HeroFactory();
                    break;
            }

      Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " +      factory.GetScooter().Name());
        }
  }

class Program
    {
        static void Main(string[] args)
        {
            VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
            chk.CheckProducts();

            chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
            chk.CheckProducts();

            Console.Read();
        }
    }

Vérifiez ici: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm il semble que la méthode Factory utilise une classe particulière (non abstraite) comme classe de base tandis que Abstract factory utilise une classe abstraite pour cela. De même, si vous utilisez une interface au lieu d'une classe abstraite, le résultat sera une implémentation différente du modèle Abstract Factory.

:RÉ


Factory Method et Abstract Factory maintiennent les clients découplés des types de béton. Les deux créent des objets, mais la méthode Factory utilise l'héritage alors que la composition d' Abstract Factory utilisée.

La Factory Method est héritée dans les sous-classes pour créer les objets concrets (produits) tandis que Abstract Factory fournissent l'interface pour créer la famille de produits connexes et la sous-classe de ces interfaces définissent comment créer des produits connexes.

Ces sous-classes, lorsqu'elles sont instanciées, sont ensuite passées dans des classes de produits où elles sont utilisées en tant que type abstrait. Les produits associés dans une Abstract Factory sont souvent implémentés en utilisant la Factory Method .


Extension de John Feminella réponse:

Apple , Banana , Cherry implémente FruitFactory et qui a une méthode appelée Create qui est le seul responsable de la création d'Apple ou Banana ou Cherry. Vous avez terminé, avec votre méthode Factory .

Maintenant, vous voulez Create une salade spéciale de vos fruits et il y a votre usine abstraite . L'usine abstraite sait comment créer votre salade spéciale de la pomme, de la banane et de la cerise.

public class Apple implements Fruit, FruitFactory {
    public Fruit Create() {
        // Apple creation logic goes here
    }
}

public class Banana implements Fruit, FruitFactory {
    public Fruit Create() {
        // Banana creation logic goes here
    }
}

public class Cherry implements Fruit, FruitFactory {
    public Fruit Create() {
        // Cherry creation logic goes here
    }
}

public class SpecialSalad implements Salad, SaladFactory {
    public static Salad Create(FruitFactory[] fruits) {
        // loop through the factory and create the fruits.
        // then you're ready to cut and slice your fruits 
        // to create your special salad.
    }
}

Méthode d'usine: vous disposez d'une fabrique qui crée des objets dérivés d'une classe de base particulière

Usine abstraite: Vous avez une usine qui crée d' autres usines , et ces usines créent à leur tour des objets dérivés de classes de base. Vous faites cela parce que souvent vous ne voulez pas créer un seul objet (comme avec la méthode Factory) - vous voulez plutôt créer une collection d'objets associés.


I think we can understand the difference between these two by seeing a Java8 example code:

  interface Something{}

  interface OneWhoCanProvideSomething {
     Something getSomething();
  }

  interface OneWhoCanProvideCreatorsOfSomething{
     OneWhoCanProvideSomething getCreator();
  }


public class AbstractFactoryExample {

    public static void main(String[] args) {
        //I need something
        //Let's create one
        Something something = new Something() {};

        //Or ask someone (FACTORY pattern)
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;

        //Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
        OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;

        //Same thing, but you don't need to write you own interfaces
        Supplier<Something> supplierOfSomething = () -> null;
        Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
    }

}

Now the question is which way of creation should you use and why: The first way (no pattern, just plain constructor): creating by yourself is not a good idea, you have to do all the work, and your client code is tied to the particular implementation.

The second way (using Factory pattern): provides you the benefit that you can pass any type of implementation, which can provide different type of something based on some condition (maybe a parameter passed to creational method).

The third way (using Abstract Factory pattern): This gives you more flexibility. You can find different types of creators of something based on some condition (maybe a parameter passed).

Notez que vous pouvez toujours sortir avec le motif Factory en combinant deux conditions ensemble (ce qui augmente légèrement la complexité du code, et le couplage), je suppose que c'est pourquoi nous voyons rarement des cas d'utilisation du modèle Abstract Factory.


//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{    
   public Dough createDough(); //Will return you family of Dough
   public Clam createClam();   //Will return you family of Clam
   public Sauce createSauce(); //Will return you family of Sauce
}

class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{

   @Override
   public Dough createDough(){
      //create the concrete dough instance that NY uses
      return doughInstance;
   }

   //override other methods
} 

Les définitions du livre de texte sont déjà fournies par d'autres réponses. Je pensais que je donnerais un exemple de cela aussi.

Donc, ici PizzaIngredientsFactory est une usine abstraite car elle fournit des méthodes pour créer une famille de produits connexes.

Notez que chaque méthode de la fabrique Abstract est une méthode Factory en elle-même. Comme createDough() est en soi une méthode d'usine dont les implémentations concrètes seront fournies par des sous-classes comme NYPizzaIngredientsFactory . Donc, en utilisant chaque endroit différent peut créer des instances d'ingrédients concrets qui appartiennent à leur emplacement.

Méthode d'usine

Fournit une instance de mise en œuvre concrète

Dans l'exemple:
- createDough() - fournit une implémentation concrète pour la pâte. Donc, ceci est une méthode d'usine

Usine abstraite

Fournit une interface pour créer une famille d'objets associés

Dans l'exemple:
- PizzaIngredientsFactory est une usine abstraite car elle permet de créer un ensemble d'objets similaires comme la Dough , les Clams , la Sauce . Pour créer chaque famille d'objets, il fournit une méthode d'usine.

Exemple de Head First modèles de conception





factory-method