建造者模式的核心思想

建造者模式是一种创建型设计模式,旨在将复杂对象的构建过程与其表示分离。该模式允许用户通过相同的构建过程创建不同的对象表示,特别适用于具有多个组成部分或配置选项的对象。

建造者模式的结构

产品类(Product)

产品类是最终要构建的复杂对象,通常包含多个部件或属性。这些部件可能具有不同的组合方式或构造顺序。

public class Computer {
    private String cpu;
    private String ram;
    private String storage;
    // 其他属性和方法
}
抽象建造者(Builder)

抽象建造者定义了创建产品各个部件的接口,通常包含构建各个部件的方法和一个返回最终产品的方法。

public interface ComputerBuilder {
    void buildCPU();
    void buildRAM();
    void buildStorage();
    Computer getResult();
}
具体建造者(ConcreteBuilder)

具体建造者实现了抽象建造者接口,负责实际构建产品的各个部件。不同的具体建造者可以创建不同的产品变体。

public class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();

    public void buildCPU() {
        computer.setCPU("Intel Core i9");
    }

    public void buildRAM() {
        computer.setRAM("32GB DDR5");
    }
    // 其他实现方法
}
指挥者(Director)

指挥者负责安排复杂对象的构建次序,它通过调用建造者的方法来逐步构建产品。

public class ComputerDirector {
    public Computer construct(ComputerBuilder builder) {
        builder.buildCPU();
        builder.buildRAM();
        builder.buildStorage();
        return builder.getResult();
    }
}

建造者模式的优点

  1. 分离构建过程与表示:客户端不需要知道对象内部的具体构造细节。

  2. 更好的控制构建过程:可以精确控制复杂对象的创建步骤。

  3. 支持不同产品变体:通过不同的具体建造者可以实现产品的多样化。

  4. 增强可读性:特别是在需要多个构造函数参数时,避免了"伸缩构造函数"问题。

建造者模式的应用场景

  1. 需要创建具有多个部件的复杂对象:当对象需要多个步骤或部件组合时特别有用。

  2. 需要创建不同表示的对象:相同构建过程需要产生不同结果时。

  3. 避免使用多个构造函数:特别是当构造函数参数过多或可选参数复杂时。

  4. 需要逐步构建对象:当对象构建需要分步骤完成时。

建造者模式的实现示例

以下是一个完整的Java实现示例:

// 产品类
public class Pizza {
    private String dough;
    private String sauce;
    private String topping;
    // setter和getter方法
}

// 抽象建造者
public interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildTopping();
    Pizza getPizza();
}

// 具体建造者
public class HawaiianPizzaBuilder implements PizzaBuilder {
    private Pizza pizza = new Pizza();

    public void buildDough() {
        pizza.setDough("cross");
    }

    public void buildSauce() {
        pizza.setSauce("mild");
    }

    public void buildTopping() {
        pizza.setTopping("ham+pineapple");
    }
    // 其他实现方法
}

// 指挥者
public class Waiter {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) {
        pizzaBuilder = pb;
    }

    public Pizza getPizza() {
        return pizzaBuilder.getPizza();
    }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildTopping();
    }
}

// 客户端代码
public class BuilderExample {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
        
        waiter.setPizzaBuilder(hawaiianPizzaBuilder);
        waiter.constructPizza();
        
        Pizza pizza = waiter.getPizza();
    }
}

建造者模式的变体

链式调用建造者

现代编程中常见的一种变体是使用链式方法调用的建造者模式,这种方法更加简洁:

public class Computer {
    private String cpu;
    private String ram;
    
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
    }
    
    public static class Builder {
        private String cpu;
        private String ram;
        
        public Builder setCPU(String cpu) {
            this.cpu = cpu;
            return this;
        }
        
        public Builder setRAM(String ram) {
            this.ram = ram;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

// 使用方式
Computer computer = new Computer.Builder()
    .setCPU("Intel i7")
    .setRAM("16GB")
    .build();
参数化的建造者

某些情况下,建造者可以接受参数来决定构建哪种类型的产品:

public interface VehicleBuilder {
    void buildEngine();
    void buildWheels();
    Vehicle getVehicle();
}

public class CarBuilder implements VehicleBuilder {
    // 实现方法
}

public class MotorcycleBuilder implements VehicleBuilder {
    // 实现方法
}

public class VehicleDirector {
    public Vehicle construct(VehicleBuilder builder) {
        builder.buildEngine();
        builder.buildWheels();
        return builder.getVehicle();
    }
}

建造者模式与其他模式的比较

  1. 与工厂模式的区别:工厂模式关注的是产品对象的整体创建,而建造者模式关注的是产品的分步构建过程。

  2. 与原型模式的区别:原型模式通过复制现有对象来创建新对象,而建造者模式是通过分步构建来创建新对象。

  3. 与组合模式的关系:建造者模式常用来构建组合模式中的复杂树形结构。

建造者模式的最佳实践

  1. 考虑使用内部类建造者:当产品类不太可能被继承时,使用内部类建造者可以简化设计。

  2. 保证构建过程的完整性:确保在调用获取产品方法前,所有必要的构建步骤都已执行。

  3. 合理处理默认值:为可选参数提供合理的默认值,简化客户端代码。

  4. 验证构建参数:在构建过程中或最终构建方法中验证参数的有效性。

  5. 考虑不可变对象:如果产品应该是不可变的,建造者模式是实现这一目标的好方法。

建造者模式在开源项目中的应用

  1. Java中的StringBuilder:虽然不是严格意义上的建造者模式,但体现了相似的思想。

  2. Android中的AlertDialog.Builder:典型的建造者模式实现。

  3. Spring中的BeanDefinitionBuilder:用于构建Spring bean定义的建造者。

  4. Lombok的@Builder注解:自动为类生成建造者模式的实现代码。

建造者模式的局限性

  1. 增加代码复杂度:对于简单对象,使用建造者模式可能过度设计。

  2. 产品类与建造者类耦合:通常需要为每个产品类创建对应的建造者类。

  3. 构建顺序的约束:如果构建步骤之间有严格的顺序要求,需要在文档中明确说明。

建造者模式的扩展思考

  1. 多级建造者:对于极其复杂的对象,可以考虑分层级建造者。

  2. 部分构建:支持部分构建,允许客户端只构建需要的部分。

  3. 撤销构建步骤:实现构建步骤的撤销功能,增加灵活性。

  4. 并行构建:对于可以并行构建的部件,考虑多线程构建优化性能。

建造者模式通过将复杂对象的构建过程分解为多个步骤,并提供统一的构建接口,极大地提高了代码的灵活性和可维护性。它在需要创建具有多个部件或配置选项的复杂对象时尤其有用,是现代面向对象设计中不可或缺的模式之一。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐