¿Cuándo es una buena idea usar métodos de fábrica dentro de un objeto en lugar de una clase de fábrica?
design-patterns
factory
factory-pattern
factory-method
Ravindra babu
fuente
fuente
Respuestas:
Me gusta pensar en los patrones de diseño en términos de que mis clases sean 'personas', y los patrones son las formas en que las personas se comunican entre sí.
Entonces, para mí, el patrón de fábrica es como una agencia de contratación. Tienes a alguien que necesitará un número variable de trabajadores. Es posible que esta persona conozca la información que necesita sobre las personas que contrata, pero eso es todo.
Entonces, cuando necesitan un nuevo empleado, llaman a la agencia de contratación y les dicen lo que necesitan. Ahora, para contratar a alguien, necesita saber muchas cosas: beneficios, verificación de elegibilidad, etc. Pero la persona que contrata no necesita saber nada de esto: la agencia de contratación se encarga de todo eso.
Del mismo modo, el uso de una Fábrica permite al consumidor crear nuevos objetos sin tener que conocer los detalles de cómo se crean o cuáles son sus dependencias, solo tienen que proporcionar la información que realmente desean.
Entonces, ahora el consumidor de ThingFactory puede obtener una Cosa, sin tener que conocer las dependencias de la Cosa, a excepción de los datos de cadena que provienen del consumidor.
fuente
within an object instead of a Factory class
. Creo que se refería al escenario en el que hace que el ctor sea privado y use un método estático para crear instancias de la clase (crear un objeto). Pero para seguir este ejemplo, primero se debe crear una instancia de laThingFactory
clase para obtenerThing
objetos, lo que hace que esto seaFactory class
efectivo.Los métodos de fábrica deben considerarse como una alternativa a los constructores, principalmente cuando los constructores no son lo suficientemente expresivos, es decir.
no es tan expresivo como:
Las clases de fábrica son útiles cuando necesita un proceso complicado para construir el objeto, cuando la construcción necesita una dependencia que no desea para la clase real, cuando necesita construir diferentes objetos, etc.
fuente
Una situación en la que personalmente encuentro clases separadas de Factory para que tenga sentido es cuando el objeto final que está tratando de crear se basa en varios otros objetos. Por ejemplo, en PHP: suponga que tiene un
House
objeto, que a su vez tiene unKitchen
y unLivingRoom
objeto, y elLivingRoom
objeto también tiene unTV
objeto dentro.El método más simple para lograr esto es hacer que cada objeto cree sus hijos en su método de construcción, pero si las propiedades están relativamente anidadas, cuando
House
falla la creación, probablemente pasará algún tiempo tratando de aislar exactamente lo que está fallando.La alternativa es hacer lo siguiente (inyección de dependencia, si le gusta el término elegante):
Aquí, si el proceso de creación de una
House
falla, solo hay un lugar para buscar, pero tener que usar esta porción cada vez que se quiera una nuevaHouse
está lejos de ser conveniente. Ingrese a las fábricas:Gracias a la fábrica aquí, el proceso de creación de una
House
se abstrae (en el sentido de que no es necesario crear y configurar cada dependencia cuando solo se desea crear unaHouse
) y, al mismo tiempo, se centraliza, lo que facilita su mantenimiento. Hay otras razones por las que el uso de Fábricas separadas puede ser beneficioso (por ejemplo, la capacidad de prueba), pero encuentro este caso de uso específico para ilustrar mejor cómo las clases de Fábrica pueden ser útiles.fuente
HouseFactory
clase?create
método. Por ejemplo, siHouse
va a tener siempre el mismo tipo deLivingRoom
cosas, entonces puede tener sentido tener sus parámetros codificados en la clase de fábrica en lugar de pasarlos como argumentos. O es posible que desee proporcionar untype
argumento a suHouseFactory::create
método si tiene algunos tipos deLivingRoom
sy tiene un interruptor dentro con los parámetros codificados para cada tipo.Es importante diferenciar claramente la idea detrás del uso de fábrica o método de fábrica. Ambos están destinados a abordar diferentes tipos de problemas de creación de objetos mutuamente excluyentes.
Seamos específicos sobre el "método de fábrica":
Lo primero es que, cuando está desarrollando una biblioteca o API que, a su vez, se utilizarán para un mayor desarrollo de aplicaciones, el método de fábrica es una de las mejores selecciones para el patrón de creación. Razón detrás; Sabemos cuándo crear un objeto de las funciones requeridas pero el tipo de objeto permanecerá indeciso o se decidirá si se pasan los parámetros dinámicos .
Ahora el punto es que se puede lograr aproximadamente lo mismo usando el patrón de fábrica en sí mismo, pero se introducirá un gran inconveniente en el sistema si el patrón de fábrica se usará para el problema resaltado anteriormente, es que su lógica de crear diferentes objetos (objetos de subclases) sea específico para alguna condición comercial, por lo que en el futuro cuando necesite ampliar la funcionalidad de su biblioteca para otras plataformas (en términos más técnicos, debe agregar más subclases de interfaz básica o clase abstracta para que la fábrica devuelva esos objetos también además de uno existente basado en algunos parámetros dinámicos), cada vez que necesite cambiar (ampliar) la lógica de la clase de fábrica, que será una operación costosa y no buena desde la perspectiva del diseño. Por otro lado, si "método de fábrica"
fuente
También son útiles cuando necesita varios "constructores" con el mismo tipo de parámetro pero con un comportamiento diferente.
fuente
Es una buena idea usar métodos de fábrica dentro del objeto cuando:
Es una buena idea utilizar la clase abstracta de fábrica cuando:
fuente
UML de
Producto: define una interfaz de los objetos que crea el método Factory.
ConcreteProduct: implementa la interfaz del producto
Creador: declara el método Factory
ConcreateCreator: implementa el método Factory para devolver una instancia de ConcreteProduct
Planteamiento del problema: cree una Fábrica de juegos utilizando los Métodos de fábrica, que definen la interfaz del juego.
Fragmento de código:
salida:
Este ejemplo muestra una
Factory
clase implementando aFactoryMethod
.Game
es la interfaz para todo tipo de juegos. Define un método complejo:createGame()
Chess, Ludo, Checkers
son diferentes variantes de juegos, que proporcionan implementación paracreateGame()
public Game getGame(String gameName)
estaFactoryMethod
enIGameFactory
claseGameFactory
crea previamente diferentes tipos de juegos en constructor. Implementa elIGameFactory
método de fábrica.El nombre del juego se pasa como argumento de línea de comando a
NotStaticFactoryDemo
getGame
inGameFactory
acepta un nombre de juego y devuelve elGame
objeto correspondiente .Fábrica:
Método de fábrica
Caso de uso:
Cuándo usarlo:
Client
no sabe qué clases concretas será necesario crear en tiempo de ejecución, pero solo quiere obtener una clase que haga el trabajo.fuente
getArea()
No es un método de fábrica en absoluto .Es realmente una cuestión de gustos. Las clases de fábrica se pueden abstraer / interconectar según sea necesario, mientras que los métodos de fábrica son más livianos (y también tienden a ser comprobables, ya que no tienen un tipo definido, pero requerirán un punto de registro conocido, similar a un servicio localizador pero para localizar métodos de fábrica).
fuente
Las clases de fábrica son útiles para cuando el tipo de objeto que devuelven tiene un constructor privado, cuando diferentes clases de fábrica establecen diferentes propiedades en el objeto de retorno, o cuando un tipo de fábrica específico se combina con su tipo concreto de retorno.
WCF usa las clases ServiceHostFactory para recuperar objetos ServiceHost en diferentes situaciones. IIS utiliza el ServiceHostFactory estándar para recuperar instancias de ServiceHost para archivos .svc , pero se usa un WebScriptServiceHostFactory para servicios que devuelven serializaciones a clientes JavaScript. ADO.NET Data Services tiene su propio DataServiceHostFactory especial y ASP.NET tiene su ApplicationServicesHostFactory ya que sus servicios tienen constructores privados.
Si solo tiene una clase que consume la fábrica, puede usar un método de fábrica dentro de esa clase.
fuente
Considere un escenario cuando tenga que diseñar una clase de Pedido y Cliente. Por simplicidad y requisitos iniciales, no siente la necesidad de fábrica para la clase de pedido y llene su solicitud con muchas declaraciones de 'nuevo pedido ()'. Las cosas funcionan bien.
Ahora aparece un nuevo requisito de que el objeto Order no se puede instanciar sin la asociación del Cliente (nueva dependencia). Ahora tiene las siguientes consideraciones.
1- Se crea una sobrecarga del constructor que funcionará solo para nuevas implementaciones. (Inaceptable). 2- Cambia las firmas de Order () y cambia cada invocación. (No es una buena práctica y un verdadero dolor).
En cambio, si ha creado una fábrica para la Clase de orden, solo tiene que cambiar una línea de código y está listo para comenzar. Sugiero la clase Factory para casi todas las asociaciones agregadas. Espero que ayude.
fuente
si desea crear un objeto diferente en términos de uso. Es útil.
fuente
Cualquier clase que difiera la creación del objeto a su subclase para el objeto con el que necesita trabajar puede verse como un ejemplo del patrón Factory.
He mencionado en detalle en otra respuesta en https://stackoverflow.com/a/49110001/504133
fuente
Creo que dependerá del grado de acoplamiento suelto que desee aportar a su código.
El método de fábrica desacopla muy bien las cosas, pero la clase de fábrica no.
En otras palabras, es más fácil cambiar las cosas si usa el método de fábrica que si usa una fábrica simple (conocida como clase de fábrica).
Mira en este ejemplo: https://connected2know.com/programming/java-factory-pattern/ . Ahora, imagina que quieres traer un nuevo animal. En la clase Factory, debe cambiar Factory, pero en el método factory, no, solo necesita agregar una nueva subclase.
fuente
Las clases de fábrica son más pesadas, pero te dan ciertas ventajas. En los casos en que necesita construir sus objetos a partir de múltiples fuentes de datos sin procesar, le permiten encapsular solo la lógica de construcción (y tal vez la agregación de datos) en un solo lugar. Allí se puede probar en abstracto sin preocuparse por la interfaz del objeto.
He encontrado que este es un patrón útil, particularmente cuando no puedo reemplazar un ORM inadecuado y quiero instanciar eficientemente muchos objetos de uniones de tablas DB o procedimientos almacenados.
fuente
Comparo las fábricas con el concepto de bibliotecas. Por ejemplo, puede tener una biblioteca para trabajar con números y otra para trabajar con formas. Puede almacenar las funciones de estas bibliotecas en directorios con nombre lógico como
Numbers
oShapes
. Estos son tipos genéricos que podrían incluir enteros, flotadores, dobules, largos o rectángulos, círculos, triángulos, pentágonos en el caso de formas.El petter de fábrica usa polimorfismo, inyección de dependencia e inversión de control.
El propósito declarado de los Patrones de Fábrica es:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Entonces, supongamos que está creando un sistema operativo o marco y está creando todos los componentes discretos.
Aquí hay un ejemplo simple del concepto del Patrón de Fábrica en PHP. Puede que no esté al 100% en todo, pero está destinado a servir como un ejemplo simple. No soy un experto.
fuente
NumbersFactory::makeNumber( 'float', 12.5 );
me está dando más que decirnew Float(12.5);
si sé que necesito unFloat
? Esto es lo que no entiendo sobre las fábricas ... ¿cuál es el punto?