Middle
Τι είναι το μοτίβο σχεδίασης 'Builder';
sobes.tech AI
Απάντηση από AI
The "Builder" design pattern is a creational pattern that provides a way to construct a complex object step by step. It separates the construction process of a complex object from its representation, allowing the same construction process to create different representations.
Key components of the pattern:
- Builder: An abstract or concrete interface (or class) defining a set of methods for step-by-step construction of product parts.
- ConcreteBuilder: A specific implementation of Builder that creates a particular representation of the product. It knows all the details of the construction.
- Director: An optional but often used class that defines the order of calling construction steps to create a specific configuration of the product.
- Product: The complex object being built. It consists of multiple parts.
Advantages:
- Allows creating complex objects step by step, avoiding "telescopic" constructors (constructors with many parameters).
- Encapsulates the logic of creating a complex object.
- Facilitates changing the internal representation of the product.
- Enables the use of the same construction process to create different variants of the product.
Applications:
- When the process of creating an object involves many steps, and these steps must be performed in a specific order.
- When different representations of the same object are needed.
- When the constructor of the object has many optional parameters.
Example:
// Product
class Pizza {
private String dough = "";
private String sauce = "";
private List<String> toppings = new ArrayList<>();
public void setDough(String dough) {
this.dough = dough;
}
public void setSauce(String sauce) {
this.sauce = sauce;
}
public void addTopping(String topping) {
this.toppings.add(topping);
}
@Override
public String toString() {
return "Pizza with dough: " + dough + ", sauce: " + sauce + ", toppings: " + toppings;
}
}
// Builder interface
interface PizzaBuilder {
void buildDough();
void buildSauce();
void buildToppings();
Pizza getPizza();
}
// Concrete Builder
class MargheritaPizzaBuilder implements PizzaBuilder {
private Pizza pizza = new Pizza();
@Override
public void buildDough() {
pizza.setDough("thin crust");
}
@Override
public void buildSauce() {
pizza.setSauce("tomato");
}
@Override
public void buildToppings() {
pizza.addTopping("mozzarella");
pizza.addTopping("basil");
}
@Override
public Pizza getPizza() {
return this.pizza;
}
}
// Director (optional)
class Cook {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder(PizzaBuilder pb) {
pizzaBuilder = pb;
}
public Pizza getPizza() {
return pizzaBuilder.getPizza();
}
public void constructPizza() {
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildToppings();
}
}
// Usage
public class BuilderExample {
public static void main(String[] args) {
Cook cook = new Cook();
PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();
cook.setPizzaBuilder(margheritaBuilder);
cook.constructPizza();
Pizza margherita = cook.getPizza();
System.out.println(margherita);
}
}
In the context of test automation, the "Builder" pattern is often used for creating test data or complex test objects (for example, a user object with many attributes, an order object with multiple items), where it is necessary to flexibly configure different variants of these data for various test scenarios.