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á un producto genérico. Mi primera pregunta es sobre la fábrica abstracta. ¿Es su función permitirle crear familias de objetos concretos (que pueden depender de la fábrica específica que 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 que llame?
Mis dos preguntas finales son sobre una sola cita que no puedo entender completamente y 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 instanciación de objetos a otro objeto a través de la composición, mientras que el patrón Factory Method usa la herencia y se basa en una subclase para manejar la instanciación de objetos deseada.
Tengo entendido que el patrón del método de fábrica tiene una interfaz Creator que hará que ConcreteCreator se encargue de saber qué ConcreteProduct creará. ¿Es esto lo que significa al usar la herencia para manejar la instanciación de objetos?
Ahora con respecto a esa cita, ¿cómo delega exactamente el patrón Abstract Factory la responsabilidad de la creación de instancias de objeto a otro objeto a través de la composición? ¿Qué significa esto? Parece que el patrón 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 sobre estos patrones.
Cualquier ayuda, especialmente con la última pregunta, sería muy apreciada.
Respuestas:
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 mucha gente confunde estos dos términos y comienza 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, puede anularse en una subclase, de ahí la segunda mitad de su presupuesto:
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 su presupuesto:
Lo que dicen es que hay un objeto A, que quiere hacer un objeto Foo. En lugar de hacer el objeto Foo en sí (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:
Y aquí hay una fábrica abstracta en uso:
fuente
SpecialFoo
que sea más claro.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
Order
clase tiene un método llamadoCreateOrderLine
)Fábrica abstracta
En el siguiente ejemplo, diseñamos una interfaz para que podamos desacoplar la creación de colas de un sistema de mensajería y, por lo tanto, podamos crear implementaciones para diferentes sistemas de colas sin tener que cambiar la base del código.
Método de fábrica
El problema en los servidores HTTP es que siempre necesitamos una respuesta para cada solicitud.
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 anulen el propósito de la
IHttpRequest
interfaz.Por lo tanto, presentamos 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 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.
Uno debe tener cuidado al usar métodos de fábrica ya que es fácil romper el LSP ( principio de sustitución de Liskov ) al crear objetos.
fuente
Button()
hacer una "familia de productos relacionados". Por ejemplo, el ejemplo canónico de GoF creaScrollBar()
yWindow()
. La ventaja es que Abstract Factory puede imponer un tema común en sus múltiples productos.La diferencia entre los patrones de diseño AbstractFactory y Factory es la siguiente:
Implementación del patrón del método de fábrica:
Implementación de patrones abstractos de fábrica:
fuente
La principal diferencia entre Abstract Factory y Factory Method es que Abstract Factory se implementa mediante Composition ; pero el Método de Fábrica es implementado por Herencia .
Sí, lo has leído correctamente: la principal diferencia entre estos dos patrones es la composición anterior y la herencia debate de .
Los diagramas UML se pueden encontrar en el libro (GoF). Quiero proporcionar ejemplos de código, porque creo que combinar los ejemplos de las dos respuestas principales en este hilo dará una mejor demostración que cualquiera de las respuestas por sí sola. Además, he usado la terminología del libro en los nombres de clases y métodos.
Fábrica abstracta
Método de la fábrica
ConcreteCreator
es el cliente. En otras palabras, el cliente es una subclase cuyo padre define elfactoryMethod()
. Es por eso que decimos que el Método de Fábrica es implementado por Herencia.Creator
clase (padre) invoca la suyafactoryMethod()
. Si eliminamosanOperation()
de la clase padre, dejando solo un método, ya no es el patrón Método de Fábrica. En otras palabras, el Método Factory no se puede implementar con menos de dos métodos en la clase padre; y uno debe invocar al otro.Misceláneos Y diversos patrones de fábrica
Tenga en cuenta que aunque el GoF define dos patrones Factory diferentes, estos no son los únicos patrones Factory existentes. Ni siquiera son necesariamente los patrones Factory más utilizados. Un tercer ejemplo famoso es el patrón de fábrica estática de Josh Bloch de Effective Java. El libro Head First Design Patterns incluye otro patrón que ellos llaman Simple Factory.
No caigas en la trampa de asumir que cada patrón de Fábrica debe coincidir con uno del GoF.
fuente
factoryMethod()
ser siempre elprotected
método en el patrón "Método de fábrica"? (Creo que sí)public
métodos de fábrica, y el método ni siquiera necesita serabstract
; pero el punto crítico es que el método está destinado a la herencia, por lo que no puede (por ejemplo) serstatic
ofinal
. He hecho el métodoprotected
yabstract
aquí para resaltar la extensibilidad (requerida).Abstract Factory es una interfaz para crear productos relacionados, pero Factory Method es solo un método. Abstract Factory puede implementarse mediante múltiples métodos de fábrica.
fuente
Considere este ejemplo para una fácil comprensión.
¿Qué proporcionan las empresas de telecomunicaciones? Banda ancha, línea telefónica y móvil, por ejemplo, y se le pide 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 dispositivos móviles, a través de su Método de fábrica donde sabe 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 dispositivos móviles, y aquí viene Abstract Factory para jugar.
Abstract Factory es, en otras palabras, la composición de otras fábricas que son responsables de crear sus propios productos y Abstract Factory sabe cómo colocar estos productos de manera más significativa con respecto a sus propias responsabilidades.
En este caso,
BundleFactory
es la Fábrica abstractaBroadbandFactory
,PhonelineFactory
yMobileFactory
son lasFactory
. Para simplificar más, estas Fábricas tendrán un Método de Fábrica para inicializar los productos individuales.Vea el ejemplo de código a continuación:
Espero que esto ayude.
fuente
static
métodos en ninguno de los patrones de fábrica de GoF. Esto está mal.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, considere 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. Según la situación, usted decide a qué tipo de fábrica debe dirigirse. Esto es como una fábrica abstracta.
He explicado aquí tanto el patrón del método Factory como el patrón abstracto de la fábrica, comenzando por no usarlos para explicar los problemas y luego resolverlos usando los patrones anteriores https://github.com/vikramnagineni/Design-Patterns/tree/master
fuente
Dejemos en claro que la mayoría de las veces en el código de producción, utilizamos un patrón de fábrica abstracto porque la clase A está programada con la interfaz B. Y A necesita crear instancias de B. Entonces, A tiene que tener un objeto de fábrica para producir instancias de B Entonces, A no depende de ninguna instancia concreta de B. Espero que ayude.
fuente
Comprende las diferencias en las motivaciones:
Suponga que está construyendo una herramienta donde tiene objetos y una implementación concreta de las interrelaciones de los objetos. Como prevé variaciones en los objetos, ha creado una indirección al asignar 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 necesitarán variantes de esos objetos.
Otra motivación bastante intrigante en esta línea de pensamiento es un caso en el que 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 podría ser un poco contra intuitivo de entender, ya que a menudo tendemos a pensar que, siempre y cuando las variantes de un objeto sigan un contrato uniforme común ( interfaz en sentido más amplio ), el código de implementación concreto nunca debería 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 GUI que diga un monitor virtual que emule la apariencia de MS o Mac o Fedora OS. Aquí, por ejemplo, cuando todos los objetos de widgets como ventanas, botones, etc. tienen una variante MS, excepto una barra de desplazamiento que se deriva de la variante MAC, el propósito de la herramienta falla gravemente.
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 construir varias herramientas ( como la de los ejemplos anteriores ) utilizando su marco. Por la sola idea 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. Si bien 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 creadores de herramientas ) tienen la libertad de decidir qué objeto construir y cómo interactuarán todos los objetos que crean. A diferencia del caso anterior ( de Abstract Factory Pattern ), usted ( como creador del framework) no es necesario trabajar con objetos concretos en este caso; y más bien puede permanecer 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 el código marco permanece en el nivel de contrato, cada constructor de herramientas está restringido ( por la naturaleza del caso mismo ) a usar sus propios objetos. Las creaciones de objetos en este caso se delegan a cada implementador y los proveedores de marcos solo proporcionan métodos uniformes para crear y devolver objetos. Dichos métodos son inevitables para que el desarrollador de marcos 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 ).
Pocas notas:
Código de muestra:
fuente
Si. La intención de Abstract Factory es:
Idealmente, debería devolver un objeto por el método que invoca el cliente.
Si. El método de fábrica usa la herencia.
AbstractFactory define un FactoryMethod y ConcreteFactory es responsable de construir un ConcreteProduct. Simplemente siga el ejemplo de código en este artículo .
Puede encontrar más detalles en publicaciones SE relacionadas:
¿Cuál es la diferencia básica entre los patrones Factory y Abstract Factory?
Patrones de diseño: Fábrica vs Método de fábrica vs Fábrica abstracta
fuente
El método de fábrica se basa en la herencia: la creación de objetos se delega en subclases, que implementan el método de fábrica para crear objetos.
Abstract Factory se basa en la composición de objetos: la creación de objetos se implementa en métodos expuestos en la interfaz de fábrica.
Diagrama de alto nivel de fábrica y patrón de fábrica abstracto,
Para obtener más información sobre el método Factory, consulte este artículo .
Para obtener más información sobre el método abstracto de fábrica, consulte este artículo .
fuente
Para hacerlo muy simple con una interfaz mínima y enfoque "// 1":
Aquí puntos importantes: 1. Los mecanismos Factory y AbstractFactory deben usar la herencia (System.Object-> byte, float ...); así que si tiene herencia en el programa, Factory (Abstract Factory no estaría allí probablemente) ya está allí por diseño 2. Creator (MyFactory) sabe sobre el tipo concreto, por lo que devuelve el objeto tipo concreto al llamante (Principal); En resumen, el tipo de retorno de fábrica sería una interfaz.
Puntos importantes: 1. Requisito: Honda crearía "Regular", "Sports", 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 se trata de crear objetos relacionados 2. El problema es que los niños de IVehicleFactory regresan y IVehicle (en lugar de concreto en la fábrica); entonces obtengo la variable padre (IVehicle); luego creo un tipo concreto real llamando a CreateSingleVehicle y luego convirtiendo el objeto primario al objeto secundario real. ¿Qué pasaría si lo hago
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
? obtendrá ApplicationException y es por eso que necesitamos una fábrica abstracta genérica que explicaría si fuera necesario.fuente
Abstract Factory : una fábrica de fábricas; una fábrica que agrupa a las fábricas individuales pero relacionadas / dependientes sin especificar sus clases concretas. Ejemplo abstracto de fábrica
Fábrica : proporciona una forma de delegar la lógica de instanciación a las clases secundarias. Ejemplo de patrón de fábrica
fuente
Yo preferiría Abstract Factory sobre Factory Method en cualquier momento. Del ejemplo de Tom Dalling (gran explicación por cierto) anterior, podemos ver que Abstract Factory es más componible, 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 Factory Method requiere que introduzcamos una nueva clase (más cosas para administrar) y usemos subclases. Siempre prefiera la composición sobre la herencia.
fuente
permíteme decirlo con precisión. la mayoría de las respuestas ya explicaron, proporcionaron diagramas y ejemplos también. así que mi respuesta sería solo un trazador de líneas. mis propias palabras: - “el patrón abstracto de fábrica agrega 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 patrones de métodos de fábrica "
fuente
Muchas de las respuestas anteriores no proporcionan comparaciones de código entre Abstract Factory y Factory Method. El siguiente es mi intento de explicarlo a través de Java. Espero que ayude a alguien que necesita una explicación simple.
fuente