simple qué pattern patrones patron objetos method fabrica ejemplo diseño conoces aparte factory-pattern factory-method design-patterns abstract-factory

factory pattern - qué - Diferencias entre el patrón abstracto de fábrica y el método de fábrica



patrones de diseño fabrica de objetos (14)

Sé que hay muchas publicaciones sobre las diferencias entre estos dos patrones, pero hay algunas cosas que no puedo encontrar.

Por lo que he estado leyendo, veo que el patrón del método de fábrica le permite definir cómo crear un solo producto concreto pero ocultando la implementación del cliente, ya que verán un producto genérico. Mi primera pregunta es sobre la fábrica abstracta. ¿Su función es permitirle crear familias de objetos concretos (que pueden depender de qué fábrica específica use) en lugar de solo un objeto concreto? ¿La fábrica abstracta solo devuelve un objeto muy grande o muchos objetos dependiendo de los métodos a los que llama?

Mis dos últimas preguntas son sobre una sola cita que no puedo entender completamente que he visto en numerosos lugares:

Una diferencia entre los dos es que con el patrón Abstract Factory, una clase delega la responsabilidad de la creación de instancias de objetos a otro objeto a través de la composición, mientras que el patrón Factory Method utiliza la herencia y se basa en una subclase para manejar la creación de instancias de objetos deseada.

Mi entendimiento es que el patrón de método de fábrica tiene una interfaz de creador que hará que ConcreteCreator se encargue de saber qué producto de concreto crear. ¿Es esto lo que significa usar la herencia para manejar la creación de instancias de objetos?

Ahora, con respecto a esa cita, ¿cómo exactamente el patrón de Abstract Factory delega la responsabilidad de la creación de instancias de objetos a otro objeto a través de la composición? ¿Qué significa esto? Parece que el patrón de Abstract Factory también usa la herencia para hacer el proceso de construcción también en mis ojos, pero de nuevo todavía estoy aprendiendo acerca de estos patrones.

Cualquier ayuda especialmente con la última pregunta, sería muy apreciada.


  1. Mi primera pregunta es sobre la fábrica abstracta. ¿Su función es permitirle crear familias de objetos concretos (que pueden depender de qué fábrica específica use) en lugar de solo un objeto concreto?

Sí. La intención de Abstract Factory es:

Proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.

  1. ¿La fábrica abstracta solo devuelve un objeto muy grande o muchos objetos dependiendo de los métodos a los que llama?

Idealmente, debería devolver un objeto por el método que invoca el cliente.

  1. Mi entendimiento es que el patrón de método de fábrica tiene una interfaz de creador que hará que ConcreteCreator se encargue de saber qué producto de concreto crear. ¿Es esto lo que significa usar la herencia para manejar la creación de instancias de objetos?

Sí. Método de fábrica utiliza la herencia.

  1. ¿El patrón abstracto de fábrica delega la responsabilidad de la creación de instancias de objetos a otro objeto mediante la composición? ¿Qué significa esto?

AbstractFactory define un Método de Fábrica y ConcreteFactory es responsable de construir un Producto de Concreto. Simplemente siga el ejemplo de código en este article .

Puedes encontrar más detalles en las publicaciones de SE relacionadas:

¿Cuál es la diferencia básica entre los patrones de fábrica y de fábrica abstracta?

Patrones de diseño: método de fábrica vs fábrica vs fábrica abstracta


La diferencia entre los dos

La principal diferencia entre un "método de fábrica" ​​y una "fábrica abstracta" es que el método de fábrica es un método único, y una fábrica abstracta es un objeto. Creo que muchas personas confunden estos dos términos y comienzan a usarlos indistintamente. Recuerdo que me costó encontrar exactamente cuál era la diferencia cuando los aprendí.

Debido a que el método de fábrica es solo un método, se puede anular en una subclase, de ahí la segunda mitad de su cita:

... el patrón Método de fábrica utiliza la herencia y se basa en una subclase para manejar la creación de instancias del objeto deseado.

La cita supone que un objeto está llamando a su propio método de fábrica aquí. Por lo tanto, lo único que podría cambiar el valor de retorno sería una subclase.

La fábrica abstracta es un objeto que tiene múltiples métodos de fábrica. Mirando la primera mitad de tu cita:

... con el patrón de Abstract Factory, una clase delega la responsabilidad de la creación de instancias de objetos a otro objeto a través de la composición ...

Lo que dicen es que hay un objeto A, que quiere hacer un objeto Foo. En lugar de hacer el objeto Foo en sí mismo (por ejemplo, con un método de fábrica), obtendrá un objeto diferente (la fábrica abstracta) para crear el objeto Foo.

Ejemplos de código

Para mostrarle la diferencia, aquí hay un método de fábrica en uso:

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

Y aquí hay una fábrica abstracta en uso:

class A { private Factory factory; public A(Factory factory) { this.factory = factory; } public void doSomething() { //The concrete class of "f" depends on the concrete class //of the factory passed into the constructor. If you provide a //different factory, you get a different Foo object. Foo f = factory.makeFoo(); f.whatever(); } } interface Factory { Foo makeFoo(); Bar makeBar(); Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName(); } //need to make concrete factories that implement the "Factory" interface here


Abstract Factory es una interfaz para crear productos relacionados, pero Factory Method es solo un método. Abstract Factory se puede implementar mediante múltiples métodos de fábrica.


Dejemos claro que la mayor parte del tiempo en el código de producción, usamos un patrón abstracto de fábrica porque la clase A está programada con la interfaz B. Y A necesita crear instancias de B. Así que A debe tener un objeto de fábrica para producir instancias de B Entonces, A no depende de ninguna instancia concreta de B. Espero que ayude.


Ejemplo de la vida real. (Fácil de recordar)

Fábrica

Imagina que estás construyendo una casa y te acercas a un carpintero por una puerta. Usted da la medida de la puerta y sus requisitos, y él construirá una puerta para usted. En este caso, el carpintero es una fábrica de puertas. Sus especificaciones son entradas para la fábrica, y la puerta es la salida o el producto de la fábrica.

Fábrica abstracta

Ahora, consideremos el mismo ejemplo de la puerta. Puede ir a un carpintero, o puede ir a una tienda de puertas de plástico o una tienda de PVC. Todos ellos son fábricas de puertas. En función de la situación, usted decide a qué tipo de fábrica necesita acercarse. Esto es como una fábrica abstracta.

He explicado aquí el patrón de método de fábrica y el patrón de fábrica abstracto, comenzando con no usarlos explicando problemas y luego resolviendo problemas usando los patrones anteriores https://github.com/vikramnagineni/Design-Patterns/tree/master


La principal diferencia entre Abstract Factory y Factory Method es que Abstract Factory se implementa mediante Composición ; pero el método de fábrica se implementa por herencia .

Sí, lo has leído correctamente: la principal diferencia entre estos dos patrones es el debate entre la antigua composición y la herencia .

No voy a reproducir los diagramas UML aquí, ya que se pueden encontrar en numerosos lugares. Quiero proporcionar ejemplos de código; sin embargo, porque creo que combinar los ejemplos de las dos respuestas principales en este hilo brindará una mejor demostración que cualquiera de las respuestas por sí sola. Además, he agregado la terminología utilizada en el libro (GoF) a los nombres de clases y métodos.

Fábrica abstracta

  1. El punto más importante a comprender aquí es que la fábrica abstracta se inyecta en el cliente. Por eso decimos que Abstract Factory es implementado por Composición. A menudo, un marco de inyección de dependencia realizaría esa tarea; pero no se requiere un marco para DI.
  2. ¡El segundo punto crítico es que las fábricas concretas aquí no son implementaciones del método de fábrica! El código de ejemplo para el método de fábrica se muestra a continuación.
  3. Y, finalmente, el tercer punto a tener en cuenta es la relación entre los productos: en este caso, las colas de salida y de respuesta. Una fábrica de concreto produce colas de Azure, la otra MSMQ. El GoF se refiere a esta relación de producto como una "familia" y es importante tener en cuenta que la familia en este caso no significa jerarquía de clases.

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étodo de fábrica

  1. El punto más importante a comprender aquí es que ConcreteCreator es el cliente. En otras palabras, el cliente es una subclase cuyo padre define el factoryMethod() . Es por esto que decimos que el Método de Fábrica se implementa por Herencia.
  2. El segundo punto crítico es recordar que el patrón de método de fábrica no es más que una especialización del patrón de método de plantilla. Los dos patrones comparten una estructura idéntica. Sólo difieren en el propósito. El método de fábrica es creacional (construye algo) mientras que el método de plantilla es de comportamiento (calcula algo).
  3. Y, finalmente, el tercer punto a tener en cuenta es que la clase Creator (padre) invoca su propio factoryMethod() . Si eliminamos anOperation() de la clase padre, dejando solo un método atrás, ya no es el patrón de método de fábrica. En otras palabras, Factory Method no se puede implementar con menos de dos métodos en la clase principal; y uno debe invocar al otro.

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

Misceláneo Y varios patrones de fábrica

Tenga en cuenta que aunque GoF define dos patrones de Fábrica diferentes, estos no son los únicos patrones de Fábrica que existen. Ni siquiera son necesariamente los patrones de fábrica más utilizados. Un tercer ejemplo famoso es el patrón de fábrica estático de Josh Bloch de Effective Java. El libro Head First Design Patterns incluye otro patrón que ellos llaman Simple Factory.

No caiga en la trampa de asumir que cada patrón de Fábrica debe coincidir con uno del GoF.


Muchas de las respuestas anteriores no proporcionan comparaciones de código entre el patrón de Abstract Factory y Factory Method. A continuación es mi intento de explicarlo a través de Java. Espero que ayude a alguien que necesite una explicación simple.

Como dice acertadamente GoF: Abstract Factory proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.

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


Para hacerlo muy simple con una interfaz mínima y enfoca "// 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; } }

Aquí puntos importantes: 1. Los mecanismos Factory & AbstractFactory deben usar la herencia (System.Object-> byte, float ...); por lo tanto, si tiene herencia en el programa, Factory (Abstract Factory no estaría allí probablemente) ya está allí por diseño 2. El creador (MyFactory) sabe sobre el tipo concreto, por lo que devuelve el objeto de tipo concreto al llamante (Principal); En resumen, el tipo de retorno de fábrica sería una interfaz.

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

Puntos importantes: 1. Requisito: Honda crearía "Regular", "Deportes", pero Hero crearía "DarkHorse", "Sports" y "Scooty". 2. ¿Por qué dos interfaces? Uno para el tipo de fabricante (IVehicleFactory) y otro para la fábrica de productos (IVehicle); otra forma de entender 2 interfaces es que la fábrica abstracta consiste en crear objetos relacionados 2. El problema es que los hijos del IVehicleFactory regresan y el IVehicle (en lugar de concreto en la fábrica); así obtengo variable padre (IVehicle); luego creo un tipo concreto al llamar a CreateSingleVehicle y luego convertir el objeto primario en el objeto secundario real. ¿Qué pasaría si hago RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular"); ; obtendrá ApplicationException y es por eso que necesitamos una fábrica de resúmenes genéricos que explicaríamos si fuera necesario. Espero que ayude de principiante a público intermedio.


Permíteme ponerlo precisamente. La mayoría de las respuestas ya han explicado, y también han proporcionado diagramas y ejemplos. así que mi respuesta solo sería un trazador de líneas. mis propias palabras: - “el patrón abstracto de fábrica se agrega a la capa abstracta sobre múltiples implementaciones de métodos de fábrica. significa que la fábrica abstracta contiene o compone uno o más de un patrón de método de fábrica ”


Yo preferiría Abstract Factory sobre Factory Method en cualquier momento. Del ejemplo anterior de Tom Dalling (gran explicación por cierto), podemos ver que Abstract Factory es más fácil de componer, ya que todo lo que tenemos que hacer es pasar una Factory diferente al constructor (inyección de dependencia del constructor en uso aquí). Pero el Método Factory requiere que introduzcamos una nueva clase (más cosas para administrar) y utilicemos subclases. Siempre prefiero la composición sobre la herencia.


Abstract factory crea una clase base con métodos abstractos que definen métodos para los objetos que deben crearse. Cada clase de fábrica que deriva la clase base puede crear su propia implementación de cada tipo de objeto.

El método de fábrica es solo un método simple utilizado para crear objetos en una clase. Por lo general, se agrega en la raíz agregada (la clase Order tiene un método llamado CreateOrderLine )

Fábrica abstracta

En el siguiente ejemplo, diseñamos una interfaz para poder desacoplar la creación de colas de un sistema de mensajería y, por lo tanto, podemos crear implementaciones para diferentes sistemas de colas sin tener que cambiar el código base.

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étodo de fábrica

El problema en los servidores HTTP es que siempre necesitamos una respuesta para cada solicitud.

public interface IHttpRequest { // .. all other methods .. IHttpResponse CreateResponse(int httpStatusCode); }

Sin el método de fábrica, los usuarios del servidor HTTP (es decir, los programadores) se verían obligados a usar clases específicas de implementación que IHttpRequest el propósito de la interfaz IHttpRequest .

Por lo tanto, introducimos el método de fábrica para que la creación de la clase de respuesta también se abstraiga.

Resumen

La diferencia es que el propósito previsto de la clase que contiene un método de fábrica no es crear objetos , mientras que una fábrica abstracta solo debe usarse para crear objetos.

Se debe tener cuidado al usar métodos de fábrica, ya que es fácil romper el LSP ( principio de sustitución de Liskovs ) al crear objetos.


Comprender las diferencias en las motivaciones:

Supongamos que está construyendo una herramienta donde tiene objetos y una implementación concreta de las interrelaciones de los objetos. Dado que prevé variaciones en los objetos, ha creado un direccionamiento indirecto asignando la responsabilidad de crear variantes de los objetos a otro objeto ( lo llamamos fábrica abstracta ). Esta abstracción encuentra un gran beneficio, ya que prevé futuras extensiones que necesitan variantes de esos objetos.

Otra motivación bastante intrigante en esta línea de pensamientos es un caso donde todos o ninguno de los objetos de todo el grupo tendrán una variante correspondiente. Según algunas condiciones, se utilizará cualquiera de las variantes y, en cada caso, todos los objetos deben ser de la misma variante. Esto puede ser un poco intuitivo de entender, ya que a menudo pensamos que, siempre que las variantes de un objeto sigan un contrato uniforme común ( interfaz en sentido amplio ), el código de implementación concreto nunca debe romperse. El hecho intrigante aquí es que, no siempre esto es cierto, especialmente cuando el comportamiento esperado no puede ser modelado por un contrato de programación.

Un simple ( tomando prestada la idea de GoF ) es cualquier aplicación de GUI que diga un monitor virtual que emula la apariencia de MS, Mac o Fedora OS. Aquí, por ejemplo, cuando todos los objetos de widget, como la ventana, el botón, etc. tienen una variante de MS, excepto una barra de desplazamiento que se deriva de la variante de MAC, el propósito de la herramienta falla.

Estos casos anteriores forman la necesidad fundamental de Abstract Factory Pattern .

Por otro lado, imagine que está escribiendo un marco para que muchas personas puedan crear varias herramientas ( como la que se muestra en los ejemplos anteriores ) utilizando su marco. Por la idea misma de un marco, no es necesario, aunque no pueda usar objetos concretos en su lógica. Prefieres poner algunos contratos de alto nivel entre varios objetos y cómo interactúan. Mientras que usted ( como desarrollador de framework ) permanece en un nivel muy abstracto, cada constructor de la herramienta se ve obligado a seguir sus construcciones de framework. Sin embargo, ellos ( los constructores de herramientas ) tienen la libertad de decidir qué objeto se construirá y cómo interactuarán todos los objetos que crean. A diferencia del caso anterior ( de Abstract Factory Pattern ), usted ( como creador del marco ) no necesita trabajar con objetos concretos en este caso; y más bien puede mantenerse en el nivel de contrato de los objetos. Además, a diferencia de la segunda parte de las motivaciones anteriores, usted o los constructores de herramientas nunca tienen la situación de mezclar objetos de variantes. Aquí, mientras que el código marco se mantiene a nivel de contrato, cada constructor de herramientas está restringido ( por la naturaleza del propio caso ) a usar sus propios objetos. Las creaciones de objetos en este caso se delegan a cada implementador y los proveedores del marco simplemente proporcionan métodos uniformes para crear y devolver objetos. Tales métodos son inevitables para que el desarrollador del marco continúe con su código y tiene un nombre especial llamado Método de fábrica ( Patrón de método de fábrica para el patrón subyacente ).

Algunas notas:

  • Si está familiarizado con el ''método de plantilla'', entonces verá que los métodos de fábrica a menudo se invocan desde los métodos de plantilla en el caso de programas relacionados con cualquier tipo de marco. Por el contrario, los métodos de plantilla de los programas de aplicación suelen ser simples implementaciones de algoritmos específicos y no incluyen métodos de fábrica.
  • Además, para completar los pensamientos, utilizando el marco ( mencionado anteriormente ), cuando un constructor de herramientas está construyendo una herramienta, dentro de cada método de fábrica, en lugar de crear un objeto concreto, él / ella puede delegar la responsabilidad a un resumen. - Objeto de fábrica, siempre que el creador de herramientas prevea variaciones de los objetos concretos para futuras extensiones.

Código de muestra:

//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 } …. }


Considere este ejemplo para una fácil comprensión.

¿Qué aporta la compañía de telecomunicaciones? Banda ancha, línea telefónica y móvil, por ejemplo, y le piden que cree una aplicación para ofrecer sus productos a sus clientes.

En general, lo que haría aquí es crear los productos, es decir, banda ancha, línea telefónica y móvil a través de su Método de fábrica, en el que sabrá qué propiedades tiene para esos productos y es bastante sencillo.

Ahora, la compañía quiere ofrecer a sus clientes un paquete de sus productos, es decir, banda ancha, línea telefónica y móvil, y aquí viene la Abstract Factory para jugar.

En otras palabras, Abstract Factory es la composición de otras fábricas que son responsables de crear sus propios productos y Abstract Factory sabe cómo colocar estos productos en más sentido con respecto a sus propias responsabilidades.

En este caso, BundleFactory es Abstract Factory, BroadbandFactory , PhonelineFactory y MobileFactory son Factory . Para simplemente más, estas fábricas tendrán el método de fábrica para inicializar los productos individuales.

Vea el ejemplo de código a continuación:

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 } }


Las diferencias entre los patrones de diseño de AbstractFactory y Factory son los siguientes:

  • Factory Method se usa para crear un solo producto, pero Abstract Factory se trata de crear familias de productos relacionados o dependientes.
  • El patrón Método de fábrica expone un método al cliente para crear el objeto, mientras que en el caso de Abstract Factory exponen una familia de objetos relacionados que pueden consistir en estos métodos de Factory.
  • El patrón del método de fábrica oculta la construcción de un solo objeto, mientras que el método de fábrica abstracto oculta la construcción de una familia de objetos relacionados. Las fábricas abstractas generalmente se implementan utilizando (un conjunto de) métodos de fábrica.
  • El patrón AbstractFactory usa la composición para delegar la responsabilidad de crear un objeto en otra clase, mientras que el patrón de diseño de Fábrica usa la herencia y se basa en la clase derivada o la subclase para crear el objeto.
  • La idea detrás del patrón de Método de Fábrica es que permite el caso en el que un cliente no sabe qué clases concretas se requerirán para crear en tiempo de ejecución, pero solo quiere obtener una clase que hará el trabajo, mientras que el patrón de AbstractFactory es el mejor utilizado cuando su sistema tiene que crear varias familias de productos o desea proporcionar una biblioteca de productos sin exponer los detalles de la implementación.

Implementación del patrón de método de fábrica:

Implementación de patrones AbstractFactory: