El patrón Builder es un patrón de diseño que separa la construcción de un objeto complejo de su representación. Esto permite que el mismo proceso de construcción cree diferentes representaciones del objeto.
El patrón Builder se utiliza a menudo cuando la construcción de un objeto es compleja o requiere mucho tiempo. También se puede utilizar cuando el objeto tiene muchas partes opcionales, de modo que el constructor pueda crear una configuración específica del objeto.
El patrón Builder funciona mediante una clase separada llamada Builder. Esta clase contiene el código para construir el objeto. El código del cliente crea un objeto Builder y luego llama a métodos en el Builder para agregar las diferentes partes del objeto. Una vez que se han agregado todas las partes, el código del cliente llama a un método en el Builder para obtener el objeto final.
Algunas de las ventajas de usar el patrón de diseño Builder son:
- Simplifica la construcción de objetos complejos.
- El patrón Builder permite construir objetos complejos paso a paso, haciendo el proceso más fácil de entender y manejar.
- Hace más fácil crear diferentes representaciones de un objeto.
- El patrón Builder permite crear diferentes representaciones de un objeto al especificar diferentes valores para las propiedades del objeto.
- Simplifica las pruebas de los objetos.
- El patrón Builder hace más fácil hacer pruebas de los objetos porque puedes crear los objetos en un ambiente controlado.
- Es más fácil que los objetos evolucionen.
- Este patrón de diseño facilita la evolución de los objetos porque puedes cambiar su proceso de construcción sin afectar el código del cliente.
Pero sobre todo, el patrón de diseño Builder puede usarse para simplificar la construcción de objetos complejos. Es una buena elección cuando la construcción de un objeto es compleja o lleva tiempo, o cuando el objeto tiene muchas partes opcionales.
Ejemplos
Aquí hay un ejemplo del patrón Builder en Java:
public class Pizza {
private String size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;
public Pizza(PizzaBuilder builder) {
this.size = builder.size;
this.cheese = builder.cheese;
this.pepperoni = builder.pepperoni;
this.bacon = builder.bacon;
}
public static class PizzaBuilder {
private String size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;
public PizzaBuilder(String size) {
this.size = size;
}
public PizzaBuilder cheese(boolean value) {
cheese = value;
return this;
}
public PizzaBuilder pepperoni(boolean value) {
pepperoni = value;
return this;
}
public PizzaBuilder bacon(boolean value) {
bacon = value;
return this;
}
public Pizza build() {
return new Pizza(this);
}
}
}
public class PizzaClient {
public static void main(String[] args) {
Pizza pizza = new Pizza.PizzaBuilder("large")
.cheese(true)
.pepperoni(true)
.bacon(true)
.build();
System.out.println(pizza);
}
}
En este ejemplo, la clase Pizza
es la clase compleja que se construye, y la clase PizzaBuilder
es la clase que se utiliza para construirla. El cliente crea un objeto PizzaBuilder
y luego llama a los métodos para establecer los diferentes atributos de la pizza. Finalmente, llama al método build()
para obtener la pizza completa.
La ventaja del patrón Builder es que permite una construcción más clara y organizada de objetos complejos, separando la construcción del objeto de su representación. Esto hace que el código sea más fácil de entender y modificar, y evita la necesidad de muchos constructores sobrecargados.
En Python, este padrón se ve así:
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def addTopping(self, topping):
self.pizza.addTopping(topping)
def setSize(self, size):
self.pizza.setSize(size)
def build(self):
return self.pizza
class Client:
def __init__(self):
self.builder = PizzaBuilder()
def createPizza(self):
self.builder.addTopping("cheese")
self.builder.addTopping("pepperoni")
self.builder.setSize(12)
return self.builder.build()
if __name__ == "__main__":
client = Client()
pizza = client.createPizza()
print(pizza)
En este ejemplo, la clase PizzaBuilder
es el constructor. La clase Cliente
crea un objeto PizzaBuilder
y luego llama a los métodos en el constructor para agregar los toppings y el tamaño de la pizza. Una vez que se ha agregado la información, la clase Client
llama al método build()
para finalizar el objeto pizza
.
El patrón Builder en C# se ve de la siguiente forma:
public class PizzaBuilder
{
private Pizza pizza;
public PizzaBuilder()
{
pizza = new Pizza();
}
public void AddTopping(string topping)
{
pizza.AddTopping(topping);
}
public void SetSize(int size)
{
pizza.SetSize(size);
}
public Pizza Build()
{
return pizza;
}
}
public class Client
{
public static void Main()
{
PizzaBuilder builder = new PizzaBuilder();
builder.AddTopping("cheese");
builder.AddTopping("pepperoni");
builder.SetSize(12);
Pizza pizza = builder.Build();
Console.WriteLine(pizza);
}
}
En este ejemplo, la clase PizzaBuilder
es el constructor. La clase Client
crea un objeto PizzaBuilder
y luego llama a métodos en el constructor para agregar los ingredientes y tamaño de la pizza. Una vez que se han agregado todas las opciones, la clase Client
llama al método Build()
para obtener el objeto pizza terminado.
Por último, en Go, este padrón de diseño podría ser como sigue:
type PizzaBuilder struct {
pizza *Pizza
}
func NewPizzaBuilder() *PizzaBuilder {
return &PizzaBuilder{
pizza: &Pizza{},
}
}
func (b *PizzaBuilder) AddTopping(topping string) {
b.pizza.Toppings = append(b.pizza.Toppings, topping)
}
func (b *PizzaBuilder) SetSize(size int) {
b.pizza.Size = size
}
func (b *PizzaBuilder) Build() *Pizza {
return b.pizza
}
func main() {
builder := NewPizzaBuilder()
builder.AddTopping("cheese")
builder.AddTopping("pepperoni")
builder.SetSize(12)
pizza := builder.Build()
fmt.Println(pizza)
}
En este ejemplo, la estructura PizzaBuilder
es el constructor. El código Client
(recordemos que en Go no hay objetos propiamente dichos) crea un objetoPizzaBuilder
y llama a los métodos en el constructor para agregar los toppings y definir el tamaño de la pizza. Una vez que toda la información se ha agregado, el código Client
llama al método Build()
para finalizar el objeto pizza
.
Comentarios