design patterns - pattern - ¿Cuál es la diferencia entre el patrón de diseño de generador y el patrón de diseño de fábrica?
factory pattern uml (26)
¿Cuál es la diferencia entre el patrón de diseño del generador y el patrón de diseño de fábrica?
¿Cuál es más ventajoso y por qué?
¿Cómo represento mis hallazgos como una gráfica si quiero probar y comparar / contrastar estos patrones?
Ambos patrones vienen por la misma necesidad: ocultar de algún código de cliente la lógica de construcción de un objeto complejo ... pero, ¿qué hace que un objeto sea "complejo" (o, a veces, complique) un objeto? Principalmente, se debe a dependencias, o más bien al estado de un objeto compuesto por estados más parciales. Puede inyectar dependencias por el constructor para establecer el estado inicial del objeto, pero un objeto puede requerir muchos de ellos, algunos estarán en un estado inicial predeterminado (solo porque deberíamos haber aprendido que establecer una dependencia predeterminada en nulo no es la forma más limpia) ) y algún otro conjunto a un estado impulsado por alguna condición. Además, hay propiedades de objetos que son algún tipo de "dependencias ajenas" pero también pueden asumir estados opcionales
Hay dos formas bien conocidas de dominar esa complejidad:
- composición / agregación: construya un objeto, construya sus objetos dependientes, luego conecte entre sí. Aquí un constructor puede hacer transparente y flexible el proceso que determina las reglas que conducen la construcción del componente.
- Polimorfismo: las reglas de construcción se declaran directamente en la definición de subtipo, por lo que tiene un conjunto de reglas para cada subtipo y alguna condición decide cuál de estas reglas se aplica para construir el objeto. Una fábrica encaja perfectamente en este escenario.
Nada impide mezclar estos dos enfoques. Una familia de productos podría abstraer la creación de objetos realizada con un constructor, un constructor podría usar fábricas para determinar qué componente del componente se instancia
Ambos son muy similares, pero si tiene una gran cantidad de parámetros para la creación de objetos con algunos de ellos opcionales con algunos valores predeterminados, vaya al patrón de generador.
Ambos son patrones de creación, para crear objetos.
1) Patrón de fábrica - Supongamos que tiene una súper clase y N número de subclases. El objeto que se crea depende de qué parámetro / valor se pasa.
2) Patrón generador - para crear un objeto complejo.
Ex: Make a Loan Object. Loan could be house loan, car loan ,
education loan ..etc. Each loan will have different interest rate, amount ,
duration ...etc. Finally a complex object created through step by step process.
Con los patrones de diseño, generalmente no existe una solución "más ventajosa" que funcione para todos los casos. Depende de lo que necesites implementar.
De Wikipedia:
- El constructor se enfoca en construir un objeto complejo paso a paso. Abstract Factory hace hincapié en una familia de objetos de productos (simples o complejos). Builder devuelve el producto como paso final, pero en lo que respecta a Abstract Factory, el producto se devuelve inmediatamente.
- El constructor a menudo construye un compuesto.
- A menudo, los diseños comienzan utilizando Factory Method (menos complicado, más personalizable, las subclases proliferan) y evolucionan hacia Abstract Factory, Prototype o Builder (más flexible, más complejo) a medida que el diseñador descubre dónde se necesita más flexibilidad.
- A veces, los patrones de creación son complementarios: Builder puede usar uno de los otros patrones para implementar qué componentes se construyen. Abstract Factory, Builder y Prototype pueden usar Singleton en sus implementaciones.
Entrada de Wikipedia para el patrón de diseño de fábrica: http://en.wikipedia.org/wiki/Factory_method_pattern
Entrada de Wikipedia para el patrón de diseño del constructor: http://en.wikipedia.org/wiki/Builder_pattern
Constructor y Fábrica de Abstractos.
El patrón de diseño de Builder es muy similar, en cierta medida, al patrón de Abstract Factory. Por eso es importante poder hacer la diferencia entre las situaciones cuando se usa una u otra. En el caso de Abstract Factory, el cliente utiliza los métodos de la fábrica para crear sus propios objetos. En el caso del Builder, la clase del Builder recibe instrucciones sobre cómo crear el objeto y luego se le solicita, pero la forma en que se junta la clase depende de la clase del Builder, este detalle hace la diferencia entre los dos patrones.
Interfaz común para productos.
En la práctica, los productos creados por los constructores de concreto tienen una estructura significativamente diferente, por lo que si no hay una razón para derivar productos diferentes, una clase padre común. Esto también distingue el patrón de Generador del patrón de Abstract Factory que crea objetos derivados de un tipo común.
Creo que, el uso y la diferencia entre los patrones de Fábrica y Constructor se pueden entender / aclarar más fácilmente en un período de tiempo determinado mientras trabajaba en la misma base de código y los requisitos cambiantes.
Desde mi experiencia, por lo general, comienzas con un patrón de Factory que incluye un par de métodos de creadores estáticos. A medida que la jerarquía de objetos se vuelve más compleja (o cuando agrega más tipos), es probable que termine haciendo que sus métodos se rellenen con más parámetros y, por no mencionar, tendrá que volver a compilar el módulo de Factory. Todas esas cosas aumentan la complejidad de sus métodos de creador, disminuyen la legibilidad y hacen que el módulo de creación sea más frágil.
Este punto posiblemente será el punto de transición. Transición del patrón de Fábrica a Constructor. Al hacerlo, crea un módulo de envoltura alrededor de los parámetros de construcción y luego podrá representar objetos nuevos (similares) agregando algunas abstracciones más (quizás) e implementaciones sin tocar la lógica real de su creación. Así que has tenido una lógica menos compleja y un código fuente compilado de nuevo.
Francamente, referirme a algo así como "tener un objeto creado en un solo paso o en varios pasos es la diferencia", ya que el único factor de diversidad no fue suficiente para que yo los distinguiera, ya que podía usar ambas formas para casi todos los casos que enfrenté. Ahora sin experimentar ningún beneficio. Así que esto es lo que finalmente he pensado.
El patrón de Factory casi puede verse como una versión simplificada del patrón de Builder.
En el patrón de Fábrica , la fábrica se encarga de crear varios subtipos de un objeto según las necesidades.
El usuario de un método de fábrica no necesita saber el subtipo exacto de ese objeto. Un ejemplo de un método de fábrica createCar
puede devolver un objeto escrito por Ford
o Honda
.
En el patrón Generador , los diferentes subtipos también se crean mediante un método de construcción, pero la composición de los objetos puede diferir dentro de la misma subclase.
Para continuar con el ejemplo de automóvil, es posible que tenga un método de creación de carros de creación que crea un objeto de tipo Honda
con un motor de 4 cilindros, o un objeto de tipo Honda
con 6 cilindros. El patrón de construcción permite esta granularidad más fina.
Los diagramas tanto del http://en.wikipedia.org/wiki/Builder_pattern del http://en.wikipedia.org/wiki/Factory_method_pattern están disponibles en Wikipedia.
El patrón de construcción se enfoca en la complejidad de crear un objeto (resuelto por "pasos")
El patrón abstracto enfatiza "solo" en la "abstracción" de objetos (múltiples pero relacionados).
El patrón de diseño del constructor describe un objeto que sabe cómo diseñar otro objeto de un tipo específico en varios pasos. Mantiene el estado necesario para el elemento de destino en cada paso intermedio. Piense en lo que atraviesa StringBuilder para producir una cadena final.
El patrón de diseño de fábrica describe un objeto que sabe cómo crear varios tipos de objetos diferentes pero relacionados en un solo paso, donde el tipo específico se elige según los parámetros dados. Piense en el sistema de serialización, donde crea el serializador y construye el objeto deseado en una sola llamada de carga.
El patrón de fábrica crea una implementación concreta de una clase en tiempo de ejecución, es decir, su intención principal es utilizar el polimorfismo para permitir que las subclases decidan qué clase instanciar. Esto significa que en el momento de la compilación no sabemos la clase exacta que se creará, mientras que el patrón Builder se ocupa principalmente de resolver el problema de los constructores telescópicos antipatrón, que surge debido a un gran número de campos opcionales de una clase. En el patrón de construcción no hay noción de polimorfismo, ya que sabemos qué objeto estamos tratando de construir en tiempo de compilación.
El único tema común de estos dos patrones es la ocultación de constructores y la creación de objetos detrás de los métodos de fábrica, y el método de construcción, para mejorar la construcción de objetos.
El patrón de fábrica le permite crear un objeto a la vez a la vez, mientras que el patrón de construcción le permite interrumpir el proceso de creación de un objeto. De esta manera, puede agregar diferentes funcionalidades durante la creación de un objeto.
El patrón del generador y el patrón de fábrica, ambos parecen bastante similares a los ojos desnudos porque ambos crean objetos para ti.
Pero hay que mirar más de cerca
Este ejemplo de la vida real hará más clara la diferencia entre los dos.
Supongamos que fuiste a un restaurante de comida rápida y ordenaste comida .
1) ¿Qué comida?
Pizza
2) ¿Qué ingredientes?
Capsicum, Tomate, Pollo BBQ, SIN PIÑA
Por lo tanto, los diferentes tipos de alimentos se elaboran según el patrón de Fábrica, pero las diferentes variantes (sabores) de un alimento en particular se realizan según el patrón del Constructor.
Diferentes tipos de alimentos
Pizza, Hamburguesa, Pasta
Variantes de pizza
Sólo queso, queso + tomate + pimiento, queso + tomate, etc.
Muestra de código
Puedes ver la implementación del código de ejemplo de ambos patrones aquí
Patrón de constructor
Patrón de fábrica
En mi humilde opinión
El constructor es una especie de fábrica más compleja.
Pero en Builder puede crear una instancia de objetos utilizando otras fábricas , que son necesarias para construir un objeto final y válido.
Entonces, hablando de la evolución de "Patrones creacionales" por complejidad, puedes pensar en ello de esta manera:
Dependency Injection Container -> Service Locator -> Builder -> Factory
En mi opinión, el patrón Builder se usa cuando se quiere crear un objeto a partir de un grupo de otros objetos y la creación de una parte debe ser independiente del objeto que se desea crear. Ayuda a ocultar la creación de una parte del cliente para que el constructor y el cliente sean independientes. Se utiliza para la creación de objetos complejos (objetos que pueden consistir en propiedades complicadas)
Si bien el patrón de fábrica especifica que desea crear objetos de una familia común y desea que se certifiquen a la vez. Se utiliza para objetos más simples.
Este es un patrón creativo, ya que se utiliza para controlar la creación de instancias de clase. El patrón de construcción se utiliza para crear objetos complejos con partes constituyentes que deben crearse en el mismo orden o utilizando un algoritmo específico. Una clase externa, conocida como el director, controla el algoritmo de construcción.
Muestra
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp_Design_Patterns
{
class BuilderDesignPattern
{
static void Main(string[] args)
{
//create a constructor object to start building
Kid aKid = new Kid();
aKid.Name = "Elizabeth";
//Elizabeth use Monkey mold to make a monkey
Console.WriteLine("{0} start making a monkey", aKid.Name);
AnimalBuilder builderA = new MonkeyBuilder();
aKid.MakeAnimal(builderA);
builderA.aAnimal.ShowMe();
//Elizabeth use Kitten mold to make a kitten
Console.WriteLine("{0} start making a kitten", aKid.Name);
AnimalBuilder builderB = new KittenBuilder();
aKid.MakeAnimal(builderB);
builderB.aAnimal.ShowMe();
Console.Read();
}
}
public abstract class AnimalBuilder
{
public Animal aAnimal;
public abstract void BuildAnimalHeader();
public abstract void BuildAnimalBody();
public abstract void BuildAnimalLeg();
public abstract void BuildAnimalArm();
public abstract void BuildAnimalTail();
}
public class MonkeyBuilder : AnimalBuilder
{
public MonkeyBuilder()
{
aAnimal = new Monkey();
}
public override void BuildAnimalHeader()
{
aAnimal.Head = "Moneky''s Head has been built";
}
public override void BuildAnimalBody()
{
aAnimal.Body = "Moneky''s Body has been built";
}
public override void BuildAnimalLeg()
{
aAnimal.Leg = "Moneky''s Leg has been built";
}
public override void BuildAnimalArm()
{
aAnimal.Arm = "Moneky''s Arm has been built";
}
public override void BuildAnimalTail()
{
aAnimal.Tail = "Moneky''s Tail has been built";
}
}
public class KittenBuilder : AnimalBuilder
{
public KittenBuilder()
{
aAnimal = new Kitten();
}
public override void BuildAnimalHeader()
{
aAnimal.Head = "Kitten''s Head has been built";
}
public override void BuildAnimalBody()
{
aAnimal.Body = "Kitten''s Body has been built";
}
public override void BuildAnimalLeg()
{
aAnimal.Leg = "Kitten''s Leg has been built";
}
public override void BuildAnimalArm()
{
aAnimal.Arm = "Kitten''s Arm has been built";
}
public override void BuildAnimalTail()
{
aAnimal.Tail = "Kitten''s Tail has been built";
}
}
public abstract class Animal
{
public string Head { get; set; }
public string Body { get; set; }
public string Leg { get; set; }
public string Arm { get; set; }
public string Tail { get; set; }
//helper method for demo the Polymorphism, so we can
//easily tell what type object it is from client.
public abstract void Eat();
//helper method for demo the result from client
public void ShowMe()
{
Console.WriteLine(Head);
Console.WriteLine(Body);
Console.WriteLine(Leg);
Console.WriteLine(Arm);
Console.WriteLine(Tail);
Eat();
}
}
public class Monkey : Animal
{
//helper method to show monkey''s property for demo purpose
public override void Eat()
{
Console.WriteLine("Since I am Monkey, I like to eat banana");
}
}
public class Kitten : Animal
{
public override void Eat()
{
Console.WriteLine("Since I am Kitten, I like to eat kitten food");
}
}
public class Kid
{
public string Name { get; set; }
//construct process to build an animal object,
//after this process completed, a object
//will be consider as a ready to use object.
public void MakeAnimal(AnimalBuilder aAnimalBuilder)
{
aAnimalBuilder.BuildAnimalHeader();
aAnimalBuilder.BuildAnimalBody();
aAnimalBuilder.BuildAnimalLeg();
aAnimalBuilder.BuildAnimalArm();
aAnimalBuilder.BuildAnimalTail();
}
}
}
La diferencia es clara En el patrón del constructor, el constructor creará un tipo específico de objeto para usted. Tienes que decir lo que el constructor tiene que construir. En el patrón de fábrica, utilizando la clase abstracta, está construyendo directamente el objeto específico.
Aquí la clase de constructor actúa como mediador entre la clase principal y las clases de tipo específicas. Más abstracción.
La fábrica abstracta es similar al constructor porque también puede construir objetos complejos. La principal diferencia es que el patrón del generador se centra en la construcción de un objeto complejo paso a paso. El énfasis del factor abstracto está en las familias de objetos de productos (simples o complejos).
Los patrones Abstract Factory & Builder son patrones creacionales pero con diferentes intenciones.
Abstract Factory Pattern enfatiza la creación de objetos para familias de objetos relacionados donde:
- Cada familia es un conjunto de clases derivadas de una clase / interfaz base común.
- Cada objeto se devuelve inmediatamente como resultado de una llamada.
El patrón del generador se enfoca en la construcción de un objeto complejo paso a paso. Desacopla la representación del proceso de construcción del objeto complejo, de modo que el mismo proceso de construcción se puede utilizar para diferentes representaciones.
- El objeto Builder encapsula la configuración del objeto complejo.
- El objeto Director conoce el protocolo de uso del Generador, donde el protocolo define todos los pasos lógicos necesarios para construir el objeto complejo.
Un ejemplo
1) usando la fábrica abstracta:
GUIFactory factory = new WindowsGUIFactory();
Button button = factory.createButton(); // **creates a WindowsButton**
2) utilizando el constructor:
GUIBuilder builder = new WindowsGUIBuilder();
Button button = builder.createButton(); // **creates a Button.**
button.setOS = OSEnum.Windows;
Como no hay una clase de WindowsButton, él (el constructor) debe encargarse de construir correctamente el botón, es decir: button.setOS = windows
.
Es similar a la comparación de TPH versus TPT en el diseño de db.
Una construcción compleja es cuando el objeto a construir se compone de otros objetos diferentes que están representados por abstracciones.
Considere un menú en McDonalds. Un menú contiene una bebida, un principal y un lado. Dependiendo de la composición de los descendientes de las abstracciones individuales, el menú creado tiene otra representación.
- Ejemplo: Cola, Big Mac, Papas Fritas
- Ejemplo: Sprite, Nuggets, Fritas Rizadas
Ahí tenemos dos instancias del menú con diferentes representaciones. El proceso de construcción a su vez sigue siendo el mismo. Se crea un menú con una bebida, un principal y un lado.
Al usar el patrón de construcción, separa el algoritmo de crear un objeto complejo de los diferentes componentes utilizados para crearlo.
En términos del patrón del constructor, el algoritmo se encapsula en el director mientras que los constructores se utilizan para crear las partes integrales. La variación del constructor utilizado en el algoritmo del director da como resultado una representación diferente porque otras partes están compuestas en un menú. La forma en que se crea un menú sigue siendo la misma.
Una diferencia notable entre Constructor y fábrica que pude distinguir fue la siguiente
Supongamos que tenemos un coche
class Car
{
bool HasGPS;
bool IsCityCar;
bool IsSportsCar;
int Cylenders;
int Seats;
public:
void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
};
En la interfaz anterior podemos obtener coche de la siguiente manera:
int main()
{
BadCar = new Car(false,false,true,4,4);
}
¿Pero qué pasa si, alguna excepción ocurre al crear los asientos? NO CONSEGUIRÁ EL OBJETO EN TODO // PERO
Supongamos que tiene implementación como la siguiente
class Car
{
bool mHasGPS;
bool mIsCityCar;
bool mIsSportsCar;
int mCylenders;
int mSeats;
public:
void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
void SetGPS(bool hasGPs=false) {mHasGPs = hasGPs;}
void SetCity(bool CityCar) {mIsCityCar = CityCar;}
void SetSports(bool SportsCar) {mIsSportsCar = SportsCar;}
void SetCylender(int Cylender) {mCylenders = Cylender;}
void SetSeats(int seat) {mSeats = seat;}
};
class CarBuilder
{
Car* mCar;
public:
CarBuilder():mCar(NULL) { mCar* = new Car(); }
~CarBuilder() { if(mCar) { delete mCar; }
Car* GetCar() { return mCar; mCar=new Car(); }
CarBuilder* SetSeats(int n) { mCar->SetSeats(n); return this; }
CarBuilder* SetCylender(int n) { mCar->SetCylender(n); return this; }
CarBuilder* SetSports(bool val) { mCar->SetSports(val); return this; }
CarBuilder* SetCity(bool val) { mCar->SetCity(val); return this; }
CarBuilder* SetGPS(bool val) { mCar->SetGPS(val); return this; }
}
Ahora puedes crear así
int main()
{
CarBuilder* bp =new CarBuilder;
Car* NewCar = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();
bp->SetSeats(2);
bp->SetSports(4);
bp->SetCity(ture);
bp->SetSports(true)
Car* Car_II= bp->GetCar();
}
Aquí, en el segundo caso, incluso si una operación falla, obtendrías el auto.
Puede ser que el coche no funcione a la perfección más tarde, pero tendría el objeto.
Debido a que Factory Method te da el Auto en una sola llamada, mientras que el Builder construye uno por uno.
Aunque, depende de las necesidades de cada uno de los cuales se debe ir.
Builder y Abstract Factory han tenido diferentes propósitos. Dependiendo del caso de uso correcto, debe seleccionar el patrón de diseño adecuado.
Características salientes del constructor :
- El patrón de generador construye un objeto complejo utilizando objetos simples y utilizando un enfoque paso a paso
- Una clase Builder construye el objeto final paso a paso. Este constructor es independiente de otros objetos.
- Reemplazo al método de fábrica / Resumen de fábrica en este escenario: demasiados argumentos para pasar del programa cliente a la clase de fábrica que pueden ser propensos a errores
- Algunos de los parámetros pueden ser opcionales, a diferencia de Factory, que obliga a enviar todos los parámetros
Características salientes de la fábrica ( fábrica simple):
- Patrón creacional
- Basado en herencia
- La fábrica devuelve un Método de fábrica (interfaz) que a su vez devuelve Objeto concreto
- Puede sustituir nuevos objetos concretos por interfaz y el cliente (el que llama) no debe conocer todas las implementaciones concretas.
- El cliente siempre accede solo a la interfaz y puede ocultar los detalles de creación de objetos en el método de Fábrica.
A menudo, los diseños comienzan utilizando Factory Method (menos complicado, más personalizable, las subclases proliferan) y evolucionan hacia Abstract Factory , Prototype o Builder (más flexible, más complejo)
Echa un vistazo a las publicaciones relacionadas:
Mantener el constructor en clase separada (interfaz fluida)
Patrones de diseño: método de fábrica vs fábrica vs fábrica abstracta
Puede consultar los siguientes artículos para más detalles:
Primero algunas cosas generales para seguir mi argumentación:
El principal desafío en el diseño de grandes sistemas de software es que deben ser flexibles y fáciles de modificar. Por esta razón, hay algunas métricas como el acoplamiento y la cohesión. Para lograr sistemas que puedan modificarse o ampliarse fácilmente en su funcionalidad sin la necesidad de rediseñar todo el sistema desde cero, puede seguir los principios de diseño (como SOLID, etc.). Después de un tiempo, algunos desarrolladores reconocieron que si seguían esos principios, existen algunas soluciones similares que funcionaron bien para problemas similares. Esas soluciones estándar resultaron ser los patrones de diseño.
Por lo tanto, los patrones de diseño son para ayudarle a seguir los principios generales de diseño con el fin de lograr sistemas de acoplamiento flexible con alta cohesión.
Respondiendo a la pregunta:
Al preguntar la diferencia entre dos patrones, tiene que preguntarse qué patrón hace que su sistema sea más flexible. Cada patrón tiene su propio propósito de organizar dependencias entre clases en su sistema.
The Abstract Factory Pattern: GoF: "Proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas".
¿Qué significa esto? Al proporcionar una interfaz como esta, la llamada al constructor de cada uno de los productos de la familia se encapsula en la clase de fábrica. Y debido a que este es el único lugar en todo su sistema donde se llama a esos constructores, usted puede alterar su sistema implementando una nueva clase de fábrica. Si intercambia la representación de la fábrica a través de otra, puede intercambiar un conjunto completo de productos sin tocar la mayoría de su código.
The Builder Pattern: GoF: "Separe la construcción de un objeto complejo de su representación para que el mismo proceso de construcción pueda crear diferentes representaciones".
Qué significa esto: Usted encapsula el proceso de construcción en otra clase, llamado director (GoF). Este director contiene el algoritmo de creación de nuevas instancias del producto (por ejemplo, componer un producto complejo de otras partes). Para crear las partes integrales de todo el producto, el director utiliza un constructor. Al intercambiar el constructor en el director, puede usar el mismo algoritmo para crear el producto, pero cambiar las representaciones de partes individuales (y, por lo tanto, la representación del producto). Para ampliar o modificar su sistema en la representación del producto, todo lo que necesita hacer es implementar una nueva clase de constructor.
En resumen, el propósito de The Abstract Factory Pattern es intercambiar un conjunto de productos que están hechos para ser usados en conjunto. El propósito de Builder Pattern es encapsular el algoritmo abstracto de crear un producto para reutilizarlo para diferentes representaciones del producto.
En mi opinión, no se puede decir que el Patrón de fábrica abstracta sea el hermano mayor del Patrón de construcción. SÍ, ambos son patrones creacionales, pero la intención principal de los patrones es completamente diferente.
Una fábrica es simplemente una función de envoltorio alrededor de un constructor (posiblemente uno en una clase diferente). La diferencia clave es que un patrón de método de fábrica requiere que todo el objeto se construya en una sola llamada de método, con todos los parámetros pasados en una sola línea. El objeto final será devuelto.
Por otro lado, un patrón de constructor es, en esencia, un objeto envoltorio alrededor de todos los parámetros posibles que podría querer pasar a una invocación de constructor. Esto le permite usar métodos de establecimiento para construir lentamente su lista de parámetros. Un método adicional en una clase de constructor es un método de construcción (), que simplemente pasa el objeto de constructor al constructor deseado y devuelve el resultado.
En lenguajes estáticos como Java, esto se vuelve más importante cuando tiene más de un puñado de parámetros (potencialmente opcionales), ya que evita el requisito de tener constructores telescópicos para todas las posibles combinaciones de parámetros. Además, un constructor le permite utilizar métodos de establecimiento para definir campos de solo lectura o privados que no se pueden modificar directamente después de que se haya llamado al constructor.
Ejemplo básico de fábrica
// Factory
static class FruitFactory {
static Fruit create(name, color, firmness) {
// Additional logic
return new Fruit(name, color, firmness);
}
}
// Usage
Fruit fruit = FruitFactory.create("apple", "red", "crunchy");
Ejemplo de Basic Builder
// Builder
class FruitBuilder {
String name, color, firmness;
FruitBuilder setName(name) { this.name = name; return this; }
FruitBuilder setColor(color) { this.color = color; return this; }
FruitBuilder setFirmness(firmness) { this.firmness = firmness; return this; }
Fruit build() {
return new Fruit(this); // Pass in the builder
}
}
// Usage
Fruit fruit = new FruitBuilder()
.setName("apple")
.setColor("red")
.setFirmness("crunchy")
.build();
Puede valer la pena comparar los ejemplos de código de estas dos páginas de wikipedia:
http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern
+-------------------------------------------------------------------+---------------------------------------------------+
| Builder | Factory |
+-------------------------------------------------------------------+---------------------------------------------------+
| Return only single instance to handle complex object construction | Retrun various instances on multiple constructors |
| No interface required | Interface driven |
| Inner classes is involved (to avoid telescopic constructors) | Subclasses are involved |
+-------------------------------------------------------------------+---------------------------------------------------+
Patrón de constructor telescópico
Analogía:
- Fábrica: Considera un restaurante. La creación de "la comida de hoy" es un patrón de fábrica, porque le dices a la cocina "tráeme la comida de hoy" y la cocina (fábrica) decide qué objeto generar, según los criterios ocultos.
- Generador: el constructor aparece si pides una pizza personalizada. En este caso, el camarero le dice al chef (constructor) "Necesito una pizza; ¡añada queso, cebollas y tocino!" Por lo tanto, el constructor expone los atributos que debe tener el objeto generado, pero oculta cómo establecerlos.
Courtesy
Construyendo un objeto complejo paso a paso: patrón de constructor
Se crea un objeto simple utilizando un solo método: patrón de método de fábrica
Creando Objeto usando el método de fábrica múltiple: patrón de fábrica abstracto