¿Cuál es la diferencia entre el patrón de diseño del constructor y el patrón de diseño de fábrica?

¿Cuál es la diferencia entre el patrón de diseño del constructor y el patrón de diseño de la fábrica?

¿Cuál es más ventajoso y por qué?

¿Cómo puedo representar mis hallazgos como un gráfico si quiero probar y comparar / contrastar estos patrones?

    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 necesite implementar.

    De la Wikipedia:

    • Builder se centra en construir un objeto complejo paso a paso. Abstract Factory enfatiza 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 con el método Factory (proliferan las subclases menos complicadas y personalizables) 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 creacionales son complementarios: el constructor 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 generador: http://en.wikipedia.org/wiki/Builder_pattern

    El patrón Factory casi se puede ver como una versión simplificada del patrón Builder.

    En el patrón Factory , la fábrica se encarga de crear diversos 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 podría devolver un objeto Ford o Honda .

    En el patrón de Generador , los diferentes subtipos también se crean mediante un método de comstackción, pero la composición de los objetos puede diferir dentro de la misma subclase.

    Para continuar el ejemplo del coche, es posible que tenga un método de creación createCar que crea un objeto tipo Honda con un motor de 4 cilindros o un objeto tipo Honda con 6 cilindros. El patrón del generador permite esta granularidad más fina.

    Los diagtwigs de los patrones Builder y Factory están disponibles en Wikipedia.

    Una fábrica es simplemente una función de envoltura 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 a método, con todos los parámetros que pasan en una sola línea. El objeto final será devuelto.

    Por otro lado, un patrón de generador es, en esencia, un objeto envoltorio alrededor de todos los parámetros posibles que puede querer pasar a una invocación de constructor. Esto le permite usar métodos setter para construir lentamente su lista de parámetros. Un método adicional en una clase de constructor es un método build (), que simplemente pasa el objeto del 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 combinaciones posibles de parámetros. También un constructor le permite usar métodos setter para definir campos privados o de solo lectura que no pueden modificarse 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 generador básico

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

    El patrón de diseño del constructor describe un objeto que sabe cómo crear otro objeto de un tipo específico en varios pasos. Mantiene el estado necesario para el elemento de destino en cada paso intermedio. Piensa en lo que StringBuilder realiza 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 en función de los parámetros dados. Piense en el sistema de serialización, donde crea su serializador y construye el objeto deseado en una sola llamada de carga.

    • Construyendo un objeto complejo paso a paso: patrón de construcción

    • Se crea un objeto simple utilizando un único método: patrón de método de fábrica

    • Creación de Objeto usando el método de fábrica múltiple: patrón abstracto de fábrica

    Ambos son patrones de Creación, para crear Objeto.

    1) Patrón de fábrica: suponga que tiene una superclase y un número N de subclases. El objeto que se crea depende de qué parámetro / valor se pasa.

    2) Patrón de 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. 

    Primero algunas cosas generales para seguir mi argumentación:

    El principal desafío al diseñar grandes sistemas de software es que deben ser flexibles y sin complicaciones para cambiar. Por esta razón, hay algunas medidas como el acoplamiento y la cohesión. Para lograr sistemas que se puedan modificar o ampliar 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 siguen esos principios hay algunas soluciones similares que funcionaron bien para problemas similares. Esas soluciones estándar resultaron ser los patrones de diseño.

    Entonces, los patrones de diseño son para ayudarle a seguir los principios generales de diseño con el fin de lograr sistemas ligeramente acoplados con alta cohesión.

    Respondiendo a la pregunta:

    Al preguntar la diferencia entre dos patrones, debe preguntarse qué patrón hace que su sistema sea más flexible. Cada patrón tiene su propio propósito para organizar dependencias entre clases en su sistema.

    Abstract Abstract Pattern: GoF: “Proporciona 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 su sistema en el que se llaman esos constructores, puede modificar su sistema implementando una nueva clase de fábrica. Si intercambia la representación de la fábrica por otra, puede intercambiar un conjunto completo de productos sin tocar la mayoría de su código.

    El patrón de construcción: GoF: “Separe la construcción de un objeto complejo de su representación para que el mismo proceso de construcción pueda crear representaciones diferentes”.

    Qué significa esto: encapsula el proceso de construcción en otra clase, llamada director (GoF). Este director contiene el algoritmo de crear nuevas instancias del producto (por ejemplo, componer un producto complejo a partir de otras partes). Para crear las partes integrales de todo el producto, el director utiliza un constructor. Al cambiar el constructor en el director, puede usar el mismo algoritmo para crear el producto, pero puede cambiar las representaciones de las partes individuales (y por lo tanto, la representación del producto). Para extender o modificar su sistema en la representación del producto, todo lo que necesita hacer es implementar una nueva clase de generador.

    En resumen: el propósito del Patrón abstracto de fábrica es intercambiar un conjunto de productos que están hechos para usarse juntos. El propósito del Patrón de creación es encapsular el algoritmo abstracto de creación de un producto para reutilizarlo para diferentes representaciones del producto.

    En mi opinión, no se puede decir que Abstract Factory Pattern sea el hermano mayor del Builder Pattern. SÍ, ambos son patrones creacionales, pero la intención principal de los patrones es completamente diferente.

    Una diferencia notable entre Builder y fábrica que pude distinguir fue la siguiente

    supongamos que tenemos un auto

     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 el automóvil de la siguiente manera:

      int main() { BadCar = new Car(false,false,true,4,4); } 

    pero ¿qué pasa si ocurre alguna excepción al crear los asientos? NO OBTENDRÁ EL OBJETO EN SU TOTALIDAD // PERO

    supongamos que tiene una 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, aún obtendría el automóvil.

    Puede ser que el auto no funcione perfectamente más tarde, pero tendrías el objeto.

    Debido a que Factory Method le proporciona el automóvil en una sola llamada, mientras que el constructor construye uno por uno.

    Aunque, depende de las necesidades del destinatario a cuál ir.

    Este es un patrón creacional, ya que se usa para controlar la instanciación de clases. El patrón del constructor se usa para crear objetos complejos con partes constituyentes que se deben crear en el mismo orden o utilizando un algoritmo específico. Una clase externa, conocida como 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(); } } } 

    Builder y Abstract Factory han tenido diferentes propósitos. Dependiendo del caso de uso correcto, debe seleccionar un patrón de diseño adecuado.

    Características destacadas del generador:

    1. Patrón de comstackción construye un objeto complejo utilizando objetos simples y usando un enfoque paso a paso
    2. Una clase de Constructor construye el objeto final paso a paso. Este constructor es independiente de otros objetos
    3. Reemplazo del método Factory / Abstract Factory en este escenario: Demasiados argumentos para pasar del progtwig cliente a la clase Factory que puede ser propenso a errores
    4. Algunos de los parámetros pueden ser opcionales a diferencia de Factory, que obliga a enviar todos los parámetros

    Fábrica ( fábrica simple) características principales:

    1. Patrón de creación
    2. Basado en la herencia
    3. La fábrica devuelve un método de fábrica (interfaz) que a su vez devuelve un objeto concreto
    4. Puede sustituir los nuevos objetos concretos por la interfaz y el cliente (llamador) no debe conocer todas las implementaciones concretas
    5. El cliente siempre accede a la interfaz solamente y puede ocultar los detalles de creación de objetos en el método Factory.

    A menudo, los diseños comienzan utilizando el Método de Fábrica (proliferan las subclases menos complicadas y más personalizables) y evolucionan hacia Abstract Factory , Prototype o Builder (más flexible, más complejo)

    Eche un vistazo a las publicaciones relacionadas:

    Mantener el constructor en una clase separada (interfaz fluida)

    Patrones de diseño: método Factory vs Factory vs Abstract Factory

    Puede consultar los artículos a continuación para obtener más detalles:

    fuente

    journaldev

    Los patrones Abstract Factory & Builder son ambos patrones Creational 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 base / interfaz común.
    • Cada objeto se devuelve inmediatamente como resultado de una llamada.

    El patrón de generador se centra en construir 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 usar para diferentes representaciones.

    • El objeto Builder encapsula la configuración del objeto complejo.
    • El objeto Director conoce el protocolo de uso del Constructor, donde el protocolo define todos los pasos lógicos requeridos para construir el objeto complejo.

    El Patrón del generador y el Patrón de fábrica parecen iguales porque ambos crean objetos para usted.

    Tienes que mirar más de cerca

    Este ejemplo de la vida real hará la diferencia entre los dos más lúcidos.

    Fuiste al restaurante de comida rápida y pediste comida .

    1) ¿Qué comida?

    Pizza

    2) ¿Qué ingredientes?

    Capsicum, tomate, pollo a la barbacoa, NO PINEAPPLE

    Entonces, los diferentes tipos de alimentos se elaboran según el patrón Factory, pero las diferentes variantes de un alimento en particular se elaboran según el patrón Builder.

    Diferentes tipos de alimentos

    Pizza, hamburguesa, pasta

    Variantes de Pizza

    Solo queso, queso + tomate + pimiento, queso + tomate, etc.

    Muestra de código

    Puede ver la implementación del código de muestra de ambos patrones aquí
    Patrón de constructor
    Patrón de fábrica

    Ambos son muy similares, pero si tiene una gran cantidad de parámetros para la creación de objetos y algunos de ellos son opcionales con algunos valores predeterminados, vaya a Patrón de generador.

     +-------------------------------------------------------------------+---------------------------------------------------+ | 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 constructor telescópico

    Analogía:

    • Fábrica: considere 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 criterios ocultos.
    • Constructor: el generador aparece si ordena 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 debería tener el objeto generado, pero oculta cómo configurarlos.

    Cortesía

    Una construcción compleja es cuando el objeto a construir se compone de otros objetos diferentes que están representados por abstracciones.

    Considera un menú en McDonalds. Un menú contiene una bebida, una principal y un lado. Dependiendo de qué descendientes de las abstracciones individuales se componen juntos, el menú creado tiene otra representación.

    1. Ejemplo: Cola, Big Mac, papas fritas
    2. Ejemplo: Sprite, Nuggets, Curly Fries

    Ahí tenemos dos instancias del menú con diferentes representaciones. El proceso de construcción a su vez sigue siendo el mismo. Usted crea un menú con una bebida, una principal y un lado.

    Al usar el patrón de construcción, se separa el algoritmo de creación de un objeto complejo a partir 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 usan para crear las partes integrales. Al variar el constructor utilizado en el algoritmo del director, se obtiene una representación diferente porque otras partes se componen de un menú. La forma en que se crea un menú sigue siendo la misma.

    El patrón de comstackción enfatiza la complejidad de crear objetos (resuelto por “pasos”)

    El patrón abstracto enfatiza “solo” en la “abstracción” de objetos (múltiples pero relacionados).

    La diferencia es clara En el patrón de generador, el constructor creará un tipo de objeto específico para usted. Tienes que decir qué constructor debe construir. En el patrón de fábrica, usando 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 tipos específicos. Más abstracción.

    Creo que el uso y la diferencia entre los patrones Factory & Builder se pueden comprender y aclarar más fácilmente en un cierto período de tiempo, ya que trabajó en la misma base de códigos y requisitos cambiantes.

    Desde mi experiencia, por lo general, comienzas con un patrón Factory que incluye un par de métodos estáticos de creador. A medida que su jerarquía de objetos se vuelva más compleja (o cuando agregue más tipos), probablemente terminará teniendo sus métodos poblados con más parámetros y sin mencionar que tendrá que recomstackr su módulo Factory. Todo eso aumenta la complejidad de los métodos de creación, disminuye la legibilidad y hace 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 Factory al Builder. Al hacerlo, crea un módulo envoltorio alrededor de los parámetros de construcción y luego podrá representar objetos nuevos (similares) agregando algunas más abstracciones (tal vez) e implementaciones sin tocar su lógica de creación real. Así que has tenido una lógica menos compleja y un código fuente recomstackdo

    Francamente, referirme a algo así como “tener un objeto creado en pasos de uno o varios pasos es la diferencia”, ya que el único factor de diversidad no era suficiente para distinguirlos, ya que podía usar ambos métodos para casi todos los casos que enfrentaba. ahora sin experimentar ningún beneficio. Así que esto es lo que finalmente pensé al respecto.

    La fábrica abstracta es similar al constructor ya que también puede construir objetos complejos. La principal diferencia es que el patrón de Builder se enfoca en construir un objeto complejo paso a paso. El énfasis del factor abstracto está en las familias de objetos de productos (simples o complejos).

    Constructor y fábrica abstracta

    El patrón de diseño de Builder es muy similar, en cierta medida, al patrón Abstract Factory. Es por eso que es importante poder marcar la diferencia entre las situaciones en las que se usa una u otra. En el caso de Abstract Factory, el cliente usa los métodos de la fábrica para crear sus propios objetos. En el caso del Constructor, se instruye a la clase de Constructor sobre cómo crear el objeto y luego se lo solicita, pero la forma en que se ensambla la clase depende de la clase del Constructor, este detalle marca 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 de padres común. Esto también distingue el patrón del generador del patrón abstracto de fábrica que crea objetos derivados de un tipo común.

    De: http://www.oodesign.com/builder-pattern.html

    En mi opinión, el patrón de Generador se usa cuando desea crear un objeto a partir de otros muchos objetos y la creación de una parte debe ser independiente del objeto que 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)

    Mientras que el patrón de fábrica especifica que desea crear objetos de una familia común y desea que se celebre a la vez. Se usa para objetos más simples.

    Ambos patrones vienen por la misma necesidad: ocultar de un 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, complicado)? Principalmente, se debe a dependencias, o más bien al estado de un objeto compuesto por más estados parciales. Puede inyectar dependencias por constructor para establecer el estado inicial del objeto, pero un objeto puede requerir muchas de ellas, algunas estarán en un estado inicial predeterminado (solo porque deberíamos haber aprendido que establecer una dependencia predeterminada a nulo no es la manera más limpia) ) y otro conjunto a un estado impulsado por alguna condición. Además, hay propiedades de objeto 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 conéctelos. Aquí un constructor puede hacer transparente y flexible el proceso que determina las reglas que conducen a la construcción del componente
    • Polimorfismo: las reglas de construcción se declaran directamente en la definición del subtipo, de modo que usted 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 puede abstraer la creación de objetos hecha con un constructor, un constructor podría usar fábricas para determinar qué objeto de instancia instanciado

    En mi humilde opinión

    El constructor es una especie de fábrica más compleja.

    Pero en Builder puede instanciar objetos con el uso de otras fábricas , que son necesarios para construir objetos finales y válidos.

    Entonces, hablando sobre la evolución de los “Patrones de Creación” por complejidad, puedes pensarlo de esta manera:

     Dependency Injection Container -> Service Locator -> Builder -> Factory 

    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 usar polymorphism para permitir que las subclases decidan qué clase instanciar. Esto significa que en el momento de la comstackción no conocemos la clase exacta que se creará, mientras que el patrón Builder se ocupa principalmente de resolver el problema de los constructores telescópicos antipattern, que surge debido a una gran cantidad de campos opcionales de una clase. En el patrón de construcción no hay noción de polymorphism, ya que sabemos qué objeto estamos intentando construir en tiempo de comstackció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 comstackción, para la construcción de objetos mejorada.

    El patrón de fábrica le permite crear un objeto a la vez al mismo tiempo, mientras que el patrón del generador le permite romper el proceso de creación de un objeto. De esta forma, puede agregar diferentes funcionalidades durante la creación de un objeto.

    Un ejemplo

    1) usando fábrica abstracta:

     GUIFactory factory = new WindowsGUIFactory(); Button button = factory.createButton(); // **creates a WindowsButton** 

    2) usando constructor:

     GUIBuilder builder = new WindowsGUIBuilder(); Button button = builder.createButton(); // **creates a Button.** button.setOS = OSEnum.Windows; 

    Como no hay una clase WindowsButton, él (el constructor) debe estar a cargo de construir correctamente el botón, es decir: button.setOS = windows .

    Es similar a la comparación de TPH frente a TPT en el diseño de db.