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

663

¿Cuál es la diferencia entre el patrón de diseño Builder y el patrón de diseño Factory?

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

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

Penguen
fuente
13
Como hacen cosas diferentes, ¿qué quieres decir con "ventajoso"?
S.Lott
55
Builder es una versión más compleja de constructor , mientras que el método de fábrica es simplificado.
Dávid Horváth
@ DávidHorváth No describiría un Builder como "más complejo". Cuando se trata de un constructor que tiene 100 parámetros, y solo le importan 3 de ellos, y sabe que la cantidad de parámetros puede cambiar en el futuro, usar el patrón Builder facilitaría la vida de todos.
Aberrante
@Aberrant El uso complicado y la complejidad arquitectónica son dos cosas diferentes. Me centré en lo último.
Dávid Horváth

Respuestas:

466

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 Wikipedia:

  • Builder se enfoca en construir un objeto complejo paso a paso. Abstract Factory enfatiza una familia de objetos de producto (ya sea simple o complejo). Builder devuelve el producto como un paso final, pero en lo que respecta a Abstract Factory, el producto se devuelve de inmediato.
  • El constructor a menudo construye un compuesto.
  • A menudo, los diseños comienzan usando el Método Factory (menos complicado, más personalizable, proliferan las subclases) 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 crean. 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

Adrian Grigore
fuente
159
Esta es exactamente la diferencia. El generador solo es necesario cuando no se puede producir un objeto en un solo paso. Un gran ejemplo de esto sería en el proceso de deserialización de un objeto complejo. Muchas veces los parámetros para el objeto complejo deben recuperarse uno por uno.
Bernard Igiri
1
Para la primera oración, diría que a menudo hay una solución más ventajosa que se aplica ampliamente ... simplemente no las vemos, porque terminan directamente en los lenguajes de programación.
Joel Coehoorn
44
@Joel: estoy de acuerdo en que algunos patrones son más comunes que otros (por ejemplo, Factory parece ser más común que Builder), pero lo que quise decir es que ninguno de ellos es siempre mejor que el otro, sin importar cómo se vea el escenario. .
Adrian Grigore
@AdrianGrigore, ¿qué pasa si se mezclan ambos? Aso.net mvc tiene ControllerBuilder que ha establecido y obtiene el método para la clase ControllerFactory
AminM
Buena respuesta, aunque 2 cosas que vale la pena agregar son: 1) Builder se utiliza principalmente para construir POJOs utilizando Fluent API (por ejemplo, Person.builder (). WithName ("Sam"). WithAge (38) .build (). 2) En mi experiencia, el generador es útil para la creación de POJO para objetos de dominio, mientras que la fábrica es útil para crear objetos de servicio como la clase PdfGeneratorFactory. El objeto de servicio podría almacenarse en caché dentro de la fábrica por más de 1 uso, mientras que el constructor siempre crea un nuevo objeto por diseño.
saurabh.in
359

Una fábrica es simplemente una función envolvente 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.

Un patrón de constructor , por otro lado, es esencialmente un objeto contenedor alrededor de todos los parámetros posibles que puede querer pasar a una invocación de constructor. Esto le permite utilizar métodos de establecimiento para construir lentamente su lista de parámetros. Un método adicional en una clase de generador es un método build (), que simplemente pasa el objeto de generador 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. Además, un generador 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 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

James McGuigan
fuente
1
Ese no es el uso correcto del patrón de generador imo, incluso en el enlace de wiki que pegó el uso es diferente. Este FruitBuilder es una combinación de componentes Director y Generador donde se invoca build () que debería pertenecer a Director y establecedores que pertenecen al componente Generador. Director debe contener lógica de negocios sobre cómo crear objetos utilizando métodos de Constructores. Las API fluidas no son patrones de construcción y StringBuilder tampoco es un patrón de construcción.
Kmaczek
282

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

En la fábrica patrón , 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 createCarpodría devolver un Fordo unHonda objeto escrito.

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

Para continuar con el ejemplo del automóvil, es posible que tenga un createCarmétodo de construcción que cree un Hondaobjeto con tipo con un motor de 4 cilindros, o un Hondaobjeto con tipo con 6 cilindros. El patrón de construcción permite esta granularidad más fina.

Los diagramas del patrón Builder y el patrón del método Factory están disponibles en Wikipedia.

Ben S
fuente
13
El patrón de construcción es como acercarse a la construcción del objeto grande. El objeto grande se compone de otro objeto que se compone más adelante como la recursividad. Mientras que la fábrica solo le conseguirá la cosa en una llamada. ¿Es correcto este entendimiento?
Fooo
63

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 pasa 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 llamada de carga.

Joel Coehoorn
fuente
77
Solo una pista: un buen ejemplo para el patrón de construcción es "interfaz fluida" y ADO.NET está lleno de implementaciones de "fábrica" ​​y "fábrica abstracta" (es decir, DbFactory).
boj
50
  • Construcción de 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 objetos mediante el método de fábrica múltiple: patrón de fábrica abstracto

Mahamudul Hasan Munna
fuente
21

Builder Pattern y Factory pattern, ambos parecen bastante similares a simple vista porque ambos crean objetos para ti

Pero necesitas mirar más de cerca

Este ejemplo de la vida real hará que la diferencia entre los dos sea más clara.

Supongamos que fuiste a un restaurante de comida rápida y pediste comida .

1) ¿Qué comida?

Pizza

2) ¿Qué coberturas?

Pimiento, tomate, pollo a la barbacoa, sin piña

Por lo tanto, los diferentes tipos de alimentos están hechos por el patrón Factory, pero las diferentes variantes (sabores) de un alimento en particular están hechas por el patrón Builder.

Diferentes tipos de alimentos

Pizza, hamburguesas, pastas

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í
Builder Pattern
Factory Pattern

Rohit Singh
fuente
1
¡Gracias por proporcionar el código de muestra! Sus ejemplos diferencian muy bien estos 2 patrones.
Rommel Paras,
18

Ambos son patrones de creación, para crear objetos.

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

2) Patrón de generador: para crear objetos complejos.

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.
Tony
fuente
12

Primero algunas cosas generales para seguir mi argumentación:

El principal desafío en el diseño de grandes sistemas de software es que tienen que ser flexibles y sin complicaciones para cambiar. 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, un desarrollador reconoció 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.

Por lo tanto, los patrones de diseño son para ayudarlo a seguir los principios generales de diseño con el fin de lograr sistemas libremente acoplados con alta cohesión.

Respondiendo 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 de organizar dependencias entre clases en su sistema.

The Abstract Factory 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 producto 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 llaman esos constructores, 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.

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 diferentes representaciones".

¿Qué significa esto ?: Encapsulas el proceso de construcción en otra clase, llamada director (GoF). Este director contiene el algoritmo de creación de 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 generador. 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 Abstract Factory Pattern es intercambiar un conjunto de productos que están hechos para usarse juntos. El propósito del patrón de construcción 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 Abstract Factory Pattern es el hermano mayor del Builder Pattern. SÍ, ambos son patrones de creación, pero la intención principal de los patrones es completamente diferente.

Janis
fuente
Buena respuesta, explicaciones elaboradas.
remolque
¿podría explicar el significado de "Separar la construcción de un objeto complejo de su representación"
Rajdeep
@Rajdeep la explicación es anhelar un comentario, por eso escribí otra respuesta.
Janis
@ Janis ¿Dónde está esa respuesta o fuente de donde puedo leer?
Rajdeep
@Rajdeep, le recomiendo que lea el libro „Patrones de diseño“ - amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/…
Janis
7

Una diferencia notable entre el constructor y la 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ÁS EL OBJETO // 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 automóvil no funcione perfectamente más tarde, pero tendría el objeto.

Porque Factory Method te da el Auto en una sola llamada, mientras que el Builder construye uno por uno.

Aunque, depende de las necesidades del diseño a cuál ir.

Fooo
fuente
2
Seguramente es mejor no tener un automóvil que un automóvil no válido: ¿qué sucede si solo encuentra el problema cuando usa los descansos?
Ken
@Ken: No insisto en que sea un buen diseño desde la perspectiva de un proyecto comercial, etc., sino más bien, la intención de citar este ejemplo para ejemplificar la diferencia entre los patrones. Definitivamente, tiene razón en que esto es malo por la experiencia del usuario de obtener un automóvil malo, pero, considere, hay una planta en la que se fabrican los automóviles y una parte está funcionando mal, entonces el automóvil se produce pero con un mal descanso que se descubriría en se detiene el tiempo de prueba y envío de ese automóvil al cliente.
Fooo
2
Me gustaría aclarar que en realidad soy un gran admirador del patrón de construcción, sin embargo, no por la razón que usted ha dado. Un objeto que no es válido debería fallar en la construcción, cuanto más abajo se encuentre un error en el proceso, más costoso será. Con el patrón de construcción, sería normal que el método de compilación (en su ejemplo llamado getCar ()) arroje una excepción si falta algún dato requerido.
Ken
7
+-------------------------------------------------------------------+---------------------------------------------------+
|                              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: considere un restaurante. La creación de la "comida de hoy" es un patrón de fábrica, porque usted le dice a la cocina "consígueme la comida de hoy" y la cocina (fábrica) decide qué objeto generar, en base a criterios ocultos.
  • Generador: el generador aparece si solicita una pizza personalizada. En este caso, el camarero le dice al chef (constructor) "¡Necesito una pizza; agréguele queso, cebolla y tocino!" Por lo tanto, el constructor expone los atributos que debe tener el objeto generado, pero oculta cómo configurarlos.

Cortesía

Premraj
fuente
5

Constructor y Fábrica Abstracta han significado diferentes propósitos. Dependiendo del caso de uso correcto, debe seleccionar un patrón de diseño adecuado.

Características destacadas del constructor :

  1. El patrón de construcción construye un objeto complejo usando objetos simples y usando un enfoque paso a paso
  2. Una clase Builder construye el objeto final paso a paso. Este constructor es independiente de otros objetos.
  3. Reemplazo al método Factory / Abstract Factory en este escenario: demasiados argumentos para pasar del programa cliente a la clase Factory que pueden ser propensos a errores
  4. Algunos de los parámetros pueden ser opcionales a diferencia de Factory, que obliga a enviar todos los parámetros

Características destacadas de fábrica ( Fábrica simple):

  1. Patrón de creación
  2. Basado en herencia
  3. Factory devuelve un Método Factory (interfaz) que a su vez devuelve Objeto concreto
  4. Puede sustituir nuevos objetos concretos por la interfaz y el cliente (llamante) 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 usando el Método Factory (menos complicado, más personalizable, proliferan las subclases) y evolucionan hacia Abstract Factory , Prototype o Builder (más flexible, más complejo)

Echa un vistazo a las publicaciones relacionadas:

Mantener el generador en una clase separada (interfaz fluida)

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

Puede consultar los siguientes artículos para obtener más detalles:

creación de fuentes

journaldev

Ravindra babu
fuente
5

Fábrica : se utiliza para crear una instancia de un objeto donde las dependencias del objeto son mantenidas por completo por la fábrica. Para el patrón de fábrica abstracta , a menudo hay muchas implementaciones concretas de la misma fábrica abstracta. La implementación correcta de la fábrica se inyecta mediante inyección de dependencia.

Generador : se utiliza para crear objetos inmutables , cuando las dependencias del objeto a instanciar se conocen en parte de antemano y el cliente del generador las proporciona en parte.

Hamady C.
fuente
4

El patrón 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 centra 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 se puede utilizar el mismo proceso de construcción para diferentes representaciones.

  • El objeto generador 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.
Saurabh Kumar
fuente
¿podría explicar el significado de "desacopla la representación del proceso de construcción del objeto complejo"
Rajdeep
3

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 McDonald's. Un menú contiene una bebida, un plato principal y un lado. Dependiendo de qué descendientes de las abstracciones individuales se componen juntas, el menú creado tiene otra representación.

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

Allí, obtuvimos dos instancias del menú con diferentes representaciones. El proceso de construcción a su vez sigue siendo el mismo. Creas un menú con una bebida, un plato principal y un lado.

Al utilizar el patrón de construcción, separa el algoritmo de creación de 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. Variar el generador usado 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.

Janis
fuente
1
Esto explica la "separación de la construcción de un objeto complejo de su representación"
Rajdeep
2

La principal diferencia entre ellos es que el patrón Builder describe principalmente la creación de objetos complejos paso a paso. En el patrón Abstract Factory, el énfasis está en las familias de objetos y productos . Builder devuelve el producto en el último paso . Mientras está en el patrón Abstract Factory, el producto está disponible de inmediato .

Ejemplo: Digamos que estamos creando Maze

1. Fábrica abstracta:

Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
 /* Call some methods on maze */
return maze;
}

2. Constructor:

Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
 /* Call some methods on builder */
return builder.GetMaze();
}
XYZCODE123
fuente
2

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

Según mi experiencia, por lo general, comienzas con un patrón Factory que incluye un par de métodos creadores estáticos para ocultar principalmente la lógica de inicialización relativamente compleja. A medida que su jerarquía de objetos se vuelve más compleja (o a medida que agrega más tipos, parámetros), probablemente termine de tener sus métodos con más parámetros y sin mencionar que tendrá que volver a compilar su módulo Factory. Todo eso aumenta la complejidad de sus métodos de creador, 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 / extensión. Al hacerlo, crea un módulo contenedor alrededor de los parámetros de construcción y luego podrá representar objetos nuevos (similares) agregando algunas abstracciones (quizás) e implementaciones sin tocar su lógica de creación real. Entonces has tenido una lógica "menos" compleja.

Francamente, hacer referencia a algo así como "tener un objeto creado en un paso o en varios pasos es la diferencia", ya que el único factor de diversidad no fue suficiente para distinguirlos, ya que podía usar ambas formas en casi todos los casos que enfrenté ahora sin experimentar ningún beneficio. Así que esto es lo que finalmente he pensado al respecto.

stdout
fuente
2

La principal ventaja del patrón de construcción sobre el patrón de fábrica es si desea crear algún objeto estándar con muchas personalizaciones posibles, pero generalmente termina personalizando solo algunas.

Por ejemplo, si desea escribir un Cliente HTTP, configurará algunos parámetros predeterminados como tiempo de espera predeterminado de escritura / lectura, protocolos, caché, DNS, interceptores, etc.

La mayoría de los usuarios de su cliente solo usarán esos parámetros predeterminados, mientras que otros usuarios pueden querer personalizar algunos de los otros parámetros. En algunos casos, solo querrá cambiar los tiempos de espera y usar el resto tal como está, mientras que en otros casos puede necesitar personalizar, por ejemplo, el caché.

Aquí hay posibles formas de crear instancias de su cliente (tomado de OkHttpClient):

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

Si usa un patrón de fábrica para esto, terminará escribiendo muchos métodos con todas las combinaciones posibles de parámetros de creación. Con el constructor, solo especifica aquellos que le importan y deja que el constructor lo construya para usted y se encargue de todos esos otros parámetros.

daneejela
fuente
1

El patrón de construcción enfatiza la complejidad de crear objetos (resuelto mediante "pasos")

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

Sandeep Jindal
fuente
1

La diferencia es clara En el patrón del generador, el generador creará un tipo específico de objeto para usted. Tienes que decir qué constructor tiene que 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.

usuario2738678
fuente
1

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, elija el patrón Builder.

Praveen Kumar
fuente
1

En mi humilde opinión

Builder es una especie de Fábrica más compleja.

Pero en Builder puedes crear instancias de objetos usando otras fábricas , que son necesarias para construir un objeto final y válido.

Entonces, hablando de la evolución de los "Patrones de creación" por complejidad, puede pensar de esta manera:

Dependency Injection Container -> Service Locator -> Builder -> Factory
v.babak
fuente
1

Ambos patrones tienen 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, complicado)? Principalmente, se debe a dependencias, o más bien al estado de un objeto compuesto por estados más parciales. Puede inyectar dependencias por 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 en 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 conecte juntos. Aquí, un constructor puede hacer transparente y flexible el proceso que determina las reglas que lideran 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 estos conjuntos de 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 crear objetos abstractos con un constructor, un generador podría usar fábricas para determinar qué objeto componente creará una instancia.

Carmine Ingaldi
fuente
0

En mi opinión, el patrón Builder se usa cuando desea crear un objeto a partir de un grupo de otros objetos y la creación de una parte debe ser independiente del objeto que desea crear. Ayuda a ocultar la creación de parte del cliente para hacer que el generador 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 cene de inmediato. Se usa para objetos más simples.

AjayLohani
fuente
0

Constructor y Fábrica Abstracta

El patrón de diseño de Builder es muy similar, en cierta medida, al patrón Abstract Factory. Por eso es importante poder marcar la diferencia entre las situaciones en que 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 constructor, la clase del constructor recibe instrucciones sobre cómo crear el objeto y luego se le pide, pero la forma en que se agrupa 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 principal común. Esto también distingue el patrón Builder del patrón Abstract Factory que crea objetos derivados de un tipo común.

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

Arturas M
fuente
-2

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 del antipatrón de los constructores telescópicos, que surge debido a una gran cantidad de campos opcionales de una clase. En el patrón de construcción no existe una noción de polimorfismo, ya que sabemos qué objeto estamos tratando de construir en el momento de la 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.

Saad
fuente
-2

El patrón de fábrica le permite crear un objeto de una vez a la vez, mientras que el patrón de construcción le permite romper el proceso de creación de un objeto. De esta manera, puede agregar diferentes funcionalidades durante la creación de un objeto.

MrWaqasAhmed
fuente