Patrón Builder
El patrón de fábrica es un patrón de diseño creacional que se utiliza para crear objetos de manera eficiente y efectiva.
El patrón de diseño Builder es un patrón de diseño creacional que se utiliza para construir objetos complejos paso a paso. Se separa la construcción de un objeto de su representación final, permitiendo que el mismo proceso de construcción pueda crear diferentes representaciones.
¿Cómo Funciona?
El patrón Builder funciona de la siguiente manera:
Director: La clase Director es la que orquesta la construcción del objeto. Sabe en qué orden llamar a los métodos del Builder para obtener el objeto final. No sabe los detalles de la construcción, solo cómo usar el Builder.
Builder: La interfaz Builder define los métodos para construir las diferentes partes del objeto. Estos métodos son abstractos y son implementados por los Concrete Builders.
Concrete Builder: Las clases Concrete Builder implementan la interfaz Builder. Se encargan de la construcción real de las partes del objeto y mantienen el estado de la construcción.
Producto: El Producto es el objeto complejo que se está construyendo. Sus partes se construyen en los Concrete
.
El cliente interactúa con el Director para iniciar la construcción. El Director utiliza un Builder para construir el objeto paso a paso y finalmente el Builder devuelve el objeto completo al cliente.
Ejemplo de Uso
Un ejemplo clásico es la construcción de una casa. Una casa es un objeto complejo con varias partes como paredes, puertas, ventanas, un techo, etc. Puedes tener diferentes tipos de casas (de madera, de ladrillo, de piedra) que, aunque tengan las mismas partes, se construyen con diferentes materiales.
Director: Un arquitecto que sabe el orden en que se construye una casa (primero los cimientos, luego las paredes, etc.).
Builder: Una interfaz "ConstructorDeCasa" con métodos como
construirParedes()
,construirPuertas()
,construirTecho()
.Concrete Builder:
ConstructorCasaDeMadera
yConstructorCasaDeLadrillo
. Cada uno implementa la interfaz de forma diferente para construir una casa de su respectivo material.Producto: La
Casa
en sí misma, con sus propiedades comoparedes
,puertas
,techo
.
Ventajas
Construcción paso a paso: Permite construir objetos de forma incremental, lo que es útil para objetos complejos con muchas partes opcionales o con un orden de construcción específico.
Código más legible: El código de creación es más claro y legible porque cada paso de la construcción está en un método con un nombre descriptivo.
Separación de responsabilidades: Separa el código de la construcción del objeto del código del objeto en sí mismo, lo que facilita el mantenimiento y la modificación.
Desventajas
Aumento de la complejidad: Introduce varias clases (Director, Builder, Concrete Builders, Product), lo que puede ser excesivo para objetos simples.
Mayor código: Se requiere más código para implementar el patrón en comparación con un constructor simple.
Ejemplo de Código
JavaScript
// Producto: la bicicleta que se va a construir
class Bicicleta {
constructor() {
this.partes = {};
}
addParte(nombre, valor) {
this.partes[nombre] = valor;
}
mostrar() {
console.log("Bicicleta construida con las siguientes partes:");
for (const parte in this.partes) {
console.log(`- ${parte}: ${this.partes[parte]}`);
}
}
}
// Builder: la clase que construye la bicicleta
class BicicletaBuilder {
constructor() {
this.bicicleta = new Bicicleta();
}
// Métodos que construyen y devuelven el builder para encadenar
conCuadro(tipo) {
this.bicicleta.addParte('cuadro', tipo);
return this;
}
conRuedas(tamano) {
this.bicicleta.addParte('ruedas', tamano);
return this;
}
conCesto() {
this.bicicleta.addParte('cesto', 'instalado');
return this;
}
conTimbre() {
this.bicicleta.addParte('timbre', 'instalado');
return this;
}
// Método final para obtener el producto terminado
build() {
return this.bicicleta;
}
}
// Uso del patrón
const miBicicleta = new BicicletaBuilder()
.conCuadro('aluminio')
.conRuedas('29 pulgadas')
.conCesto()
.build();
miBicicleta.mostrar();
console.log('---');
const bicicletaDeCarreras = new BicicletaBuilder()
.conCuadro('carbono')
.conRuedas('700c')
.conTimbre()
.build();
bicicletaDeCarreras.mostrar();
Explicación del Código
La clase
Bicicleta
es nuestro Producto. Tiene un métodoaddParte
para agregar componentes y un métodomostrar
para ver la configuración final.La clase
BicicletaBuilder
es nuestro Builder. Su constructor crea una nueva instancia deBicicleta
.Los métodos como
conCuadro
,conRuedas
,conCesto
, yconTimbre
son los "constructores" de partes. Cada uno añade una parte a la bicicleta y, crucialmente, devuelvethis
, la propia instancia deBicicletaBuilder
. Esto es lo que permite el encadenamiento de métodos (.conCuadro(...).conRuedas(...)
).El método
build()
es el que finaliza la construcción y devuelve el objetoBicicleta
ya completo.El código de uso demuestra cómo crear diferentes tipos de bicicletas (
miBicicleta
ybicicletaDeCarreras
) utilizando el mismo proceso de construcción, pero con diferentes partes.
Este enfoque mejora la legibilidad y flexibilidad del código, especialmente cuando el objeto tiene muchas opciones de configuración.
Fuentes
Última actualización