web-dev-qa-db-fra.com

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

Je lisais des motifs sur un site web

J'y ai lu des articles sur Factory, Factory method et Abstract factory, mais ils sont tellement déroutants que je ne comprends pas bien la définition. Selon les définitions

Factory - Crée des objets sans exposer la logique d'instanciation au client et fait référence au nouvel objet créé via une interface commune. est une version simplifiée de la méthode d'usine

Méthode Factory - Définit une interface pour la création d'objets, mais laisse les sous-classes décider de la classe à instancier et fait référence au nouvel objet créé via une interface commune.

Abstract Factory - Offre l'interface pour créer une famille d'objets liés sans spécifier explicitement leurs classes.

J'ai aussi regardé les autres threads stackoverflow concernant la méthode Abstract Factory vs Factory, mais les diagrammes UML dessinés ici rendent ma compréhension encore pire.

Quelqu'un peut-il me dire s'il vous plaît

  1. Comment ces trois modèles sont-ils différents les uns des autres?
  2. Quand utiliser lequel?
  3. Et aussi, si possible, des exemples Java liés à ces modèles?
156

Les trois types d’usines font la même chose: c’est un "constructeur intelligent".

Supposons que vous souhaitiez créer deux types de fruits: Apple et Orange.

Usine

Factory est "corrigé", en ce sens que vous ne disposez que d'une implémentation sans sous-classement. Dans ce cas, vous aurez une classe comme celle-ci:

class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

Cas d'utilisation: Construire un Apple ou un Orange est un peu trop complexe à gérer dans le constructeur.

Méthode d'usine

La méthode d'usine est généralement utilisée lorsque vous avez un traitement générique dans une classe, mais que vous souhaitez modifier le type de fruit que vous utilisez réellement. Alors:

abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

... alors vous pouvez réutiliser les fonctionnalités communes dans FruitPicker.pickFruit() en implémentant une méthode fabrique dans les sous-classes:

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

Usine abstraite

Abstract Factory est normalement utilisé pour des tâches telles que l’injection de dépendances/la stratégie, lorsque vous voulez pouvoir créer toute une famille d’objets devant être du même type et avoir des classes de base communes. Voici un exemple vaguement lié aux fruits. Le cas d'utilisation ici est que nous voulons nous assurer que nous n'utilisons pas accidentellement un OrangePicker sur un Apple. Tant que nous aurons nos fruits et notre ramasseur dans la même usine, ils seront identiques.

interface PlantFactory {

  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}
212
Anders Johansen
  1. Comment ces trois modèles sont-ils différents les uns des autres?

Usine: Crée des objets sans exposer la logique d'instanciation au client.

Méthode Factory: Définit une interface pour la création d'un objet, mais laisse les sous-classes décider de la classe à instancier. La méthode Factory permet à une classe de différer l'instanciation en sous-classes

Abstract Factory: Fournit une interface permettant de créer des familles d’objets apparentés ou dépendants sans spécifier leurs classes concrètes.

AbstractFactory pattern utilise la composition pour déléguer la responsabilité de la création d'un objet à une autre classe, tandis que la méthode Factory utilise le mode de héritage et repose sur la classe dérivée ou sous classe pour créer un objet

  1. Quand utiliser lequel?

Usine: Le client a simplement besoin d'une classe et ne se soucie pas de l'implémentation concrète qu'il obtient.

Méthode d'usine: Le 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 fera le travail. .

AbstactFactory: Lorsque votre système doit créer plusieurs familles de produits ou que vous souhaitez fournir une bibliothèque de produits sans exposer les détails de la mise en oeuvre.

Les classes Abstract Factory sont souvent implémentées avec la méthode Factory. Les méthodes d'usine sont généralement appelées dans les méthodes de modèle.

  1. Et aussi, si possible, des exemples Java liés à ces modèles?

Factory et FactoryMethod

Intention:

Définissez une interface pour créer un objet, mais laissez les sous-classes décider quelle classe instancier. La méthode d'usine permet à une classe de différer l'instanciation en sous-classes.

diagramme UML :

enter image description here

Produit: Définit une interface des objets créés par la méthode Factory.

ConcreteProduct: Implémente l'interface du produit.

Créateur: Déclare la méthode Factory.

ConcreateCreator: Implémente la méthode Factory pour renvoyer une instance d'un ConcreteProduct.

Énoncé du problème: Créez une usine de jeux à l’aide des méthodes d’usine, qui définissent l’interface du jeu.

Extrait de code:

Modèle d'usine. Quand utiliser les méthodes d'usine?

Comparaison avec d'autres modèles de création:

  1. La conception a commencé en utilisant la méthode Factory (moins complexe, plus personnalisable, les sous-classes se multiplient) et évolue vers Abstract Factory, Prototype , ou Builder (plus flexible, plus complexe) à mesure que le concepteur découvre où davantage de flexibilité est nécessaire

  2. Les classes abstraites Factory sont souvent implémentées avec des méthodes Factory , mais elles peuvent aussi être implémenté en utilisant Prototype

Références pour en savoir plus: modèles de conception de la fabrication de la source

22
Ravindra babu

Factory - Classe Factory séparée pour créer un objet complexe.

Ex: classe FruitFactory pour créer un objet de Fruit

class FruitFactory{

public static Fruit getFruit(){...}

}

Méthode d'usine - Au lieu d'une classe entière séparée pour une usine, ajoutez simplement une méthode dans cette classe elle-même en tant qu'usine.

Ex:

Calendar.getInstance() (Java's Calendar)

Méthode d'usine abstraite - Usine d'usine

Ex: Disons que nous voulons construire une usine pour les pièces d'ordinateur. Il existe donc plusieurs types d’ordinateurs tels que Laptop, Desktop, Server.

Donc, pour chaque type de calcul, nous avons besoin d’usine. Nous créons donc une usine d’usines de haut niveau, comme ci-dessous.

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Maintenant, ces 3 mêmes sont à nouveau des usines. (Vous traiterez avec PartFactory lui-même, mais sous le capot, il y aura une implémentation séparée basée sur ce que vous avez fourni dans abstract factory)

  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

EDIT: édité pour fournir des interfaces exactes pour Abstract Factory conformément aux objections dans les commentaires.

17
Ravi K

Chaque modèle de conception s'efforce de faire en sorte que le code écrit et fonctionnel ne soit pas touché. Nous savons tous qu'une fois que nous avons touché le code de travail, il existe des défauts dans les flux de travail existants, et beaucoup plus de tests doivent être effectués pour nous assurer de ne rien casser.

Un modèle d'usine crée des objets en fonction de critères d'entrée, vous assurant ainsi que vous n'avez pas besoin d'écrire de code comme si cela créait ce même objet, sinon cet objet. Un site Web de voyage en est un bon exemple. Un site Web de voyage ne peut proposer que des voyages (vol, train, bus) et/ou des hôtels ou/et des forfaits pour les attractions touristiques. Désormais, lorsqu'un utilisateur sélectionne ensuite, le site Web doit décider des objets à créer. Devrait-il uniquement créer l’objet de voyage ou d’hôtel?.

Maintenant, si vous envisagez d'ajouter un autre site Web à votre portefeuille et que vous pensez utiliser le même noyau, par exemple un site de covoiturage, qui recherche maintenant les taxis et effectue des paiements en ligne, vous pouvez utiliser une usine abstraite. De cette façon, vous pouvez simplement installer une autre usine de taxis et de covoiturages.

Les deux usines n'ont rien à voir l'une avec l'autre, c'est donc un bon design pour les garder dans des usines différentes.

J'espère que c'est clair maintenant. Étudiez à nouveau le site Web en gardant cet exemple à l'esprit, espérons que cela vous aidera. Et j'espère vraiment avoir bien représenté les motifs :).

10
Siddharth

Pour cette réponse, je me réfère au livre "Gang of Four".

Il y a non "Usine" ni "Usine simple" ni "Usine virtuelle" dans le livre. Habituellement quand les gens parlent du motif "Factory" dont ils peuvent parler quelque chose qui crée un objet particulier d'une classe (mais pas du motif "constructeur"); ils peuvent ou non se référer aux modèles "Méthode d'usine" ou "Usine abstraite". N'importe qui peut implémenter "Factory" comme il ne le fera pas car ce n'est pas un terme formel (gardez à l'esprit que certaines personnes/entreprises/communautés peuvent avoir leur propre vocabulaire).

Le livre niquement contient les définitions de "Abstract Factory" et "Factory Method".

Voici les définitions du livre et une brève explication de la raison pour laquelle les deux peuvent être si déroutants. J'omets des exemples de code car vous pouvez les trouver dans d'autres réponses:

Méthode d'usine (GOF): Définissez une interface pour la création d'un objet, mais laissez les sous-classes décider de la classe à instancier. La méthode d'usine permet à une classe de différer l'instanciation en sous-classes.

Abstract Factory (GOF): fournit une interface permettant de créer des familles d’objets apparentés ou dépendants sans spécifier leurs classes concrètes.

Source de confusion: Souvent, on peut appeler une classe utilisée dans le motif "Factory Method" en tant que "Factory". Cette classe est abstraite par définition. C'est pourquoi il est facile d'appeler cette classe "Fabrique abstraite". Mais c'est juste le nom de la classe; vous ne devez pas le confondre avec le motif "Abstract Factory" (nom de classe! = nom du motif). Le modèle "Abstract Factory" est différent - il utilise pas utilise une classe abstraite; il définit une interface (pas nécessairement une interface de langage de programmation) pour créer des parties d'un objet plus grand ou d'objets liés les uns aux autres ou devant être créés d'une manière particulière.

1
Pavel Sapehin
AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB

interface Factory {
    AbstractProductA getProductA(); //Factory Method - generate A1/A2
}

À l'aide de la méthode d'usine, l'utilisateur peut créer A1 ou A2 de AbstractProductA.

interface AbstractFactory {
    AbstractProductA getProductA(); //Factory Method
    AbstractProductB getProductB(); //Factory Method
}

Mais Abstract Factory ayant plus d'une méthode d'usine (ex: 2 méthodes d'usine), en utilisant ces méthodes d'usine, il créera l'ensemble des objets/objets associés. À l’aide de Abstract Factory, l’utilisateur peut créer des objets A1, B1 de AbstractProductA, AbstractProductB.

1
rameshvanka