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.
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.
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
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.
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
)
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(/*....*/);
}
}
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.
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.
Les différences entre les modèles de conception AbstractFactory et Factory sont les suivantes:
Implémentation de modèle de méthode d'usine:
Implémentation du motif AbstractFactory:
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.
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.
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
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
ConcreteCreator
est 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.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.
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.
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:
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
}
….
}
- 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.
- 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.
- 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.
- 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?
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.
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
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.
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,
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 .
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 ”
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();
}
}
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