0115_建造者模式(Builder)

建造者模式(Builder)

意图

将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

UML 图

7dd1879f43ee89771a34474486fb0461

优点

  1. 封装性好:建造者模式将复杂对象的构建过程封装在具体的建造者中,客户端无需知道内部细节
  2. 构建与表示分离:将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示
  3. 易于扩展:增加新的具体建造者无需修改原有代码,符合"开闭原则"
  4. 更好的控制构建过程:可以更精细地控制复杂对象的构建步骤和顺序

缺点

  1. 产品需要有共同点:建造者模式所创建的产品一般具有较多的共同点,如果产品之间的差异性很大,则不适合使用建造者模式
  2. 增加了系统复杂度:如果产品的内部变化复杂,可能会导致需要定义很多具体建造者来实现这种变化
  3. 需要创建多个建造者:对于不同类型的产品,需要编写不同的建造者类,增加了系统的类数量

代码示例

以下是一个建造者模式示例,模拟构建不同类型的人类。正常人包含头、手臂、腿、身体,残疾人包含手臂、腿、身体会有一些缺陷。

1. 产品类 (Product)

//人类对象
public class Human {
    // 头部属性
    private String head;
    // 手臂属性
    private String arms;
    // 腿部属性
    private String legs;
    // 身体属性
    private String body;

    /**
     * 设置头部
     * @param head 头部描述
     */
    public void setHead(String head) {
        this.head = head;
    }

    /**
     * 设置手臂
     * @param arms 手臂描述
     */
    public void setArms(String arms) {
        this.arms = arms;
    }

    /**
     * 设置腿部
     * @param legs 腿部描述
     */
    public void setLegs(String legs) {
        this.legs = legs;
    }

    /**
     * 设置身体
     * @param body 身体描述
     */
    public void setBody(String body) {
        this.body = body;
    }
}

2. 抽象建造者 (Abstract Builder)

// 人类建造者接口
public interface Builder{

    /**
     * 构建头部
     */
    void buildHead();

    /**
     * 构建身体
     */
    void buildBody();

    /**
     * 构建腿部
     */
    void buildLegs();

    /**
     * 构建手臂
     */
    void buildArms();

    Human build();
}

3. 具体建造者 (Concrete Builders)

// 正常人建造者
public class NormalHumanBuilder implements Builder{
    private Human human;
    public NormalHumanBuilder() {
        human = new Human();
    }
    public void buildHead() {
        human.setHead("建造头部 - 完整");
    }

    public void buildBody() {
        human.setBody("建造身体 - 完整");
    }

    public void buildLegs() {
        human.setLegs("建造腿部 - 完整");
    }

    public void buildArms() {
        human.setArms("建造手臂 - 完整");
    }
    public Human build() {
        return human;
    }

}

// 残疾人建造者
public class DisabledHumanBuilder implements Builder {
    private Human human;
    
    public DisabledHumanBuilder() {
        human = new Human();
    }
    
    @Override
    public void buildHead() {
        human.setHead("建造头部 - 完整");
    }

    @Override
    public void buildBody() {
        human.setBody("建造身体 - 有缺陷");
    }

    @Override
    public void buildLegs() {
        human.setLegs("建造腿部 - 残缺");
    }

    @Override
    public void buildArms() {
        human.setArms("建造手臂 - 残缺");
    }
    
    /**
     * 构建并返回残疾人对象
     * @return 构建完成的残疾人对象
     */
    public Human build() {
        return human;
    }
}

4. 指挥者 (Director)

public class Director {
    // 持有具体建造者的引用
    private Builder builder;

    /**
     * 构造方法,注入具体建造者
     * @param builder 具体的建造者实现
     */
    public Director(Builder builder) {
        this.builder = builder;
    }

    /**
     * 创建人类对象的方法
     * 按照头、身体、腿、手臂的顺序构建人类
     * @return 构建完成的人类对象
     */
    public Human createHuman() {
        // 构建头部
        builder.buildHead();
        // 构建身体
        builder.buildBody();
        // 构建腿部
        builder.buildLegs();
        // 构建手臂
        builder.buildArms();
        // 返回构建完成的产品
        return builder.build();
    }
}

5. 客户端代码 (Client Code)

public static void main(String[] args) {
        // 创建正常人类建造者
        Builder normalBuilder = new NormalHumanBuilder();
        // 创建残疾人建造者
        Builder disabledBuilder = new DisabledHumanBuilder();

        // 创建指导者并传入正常人类建造者
        Director normalDirector = new Director(normalBuilder);
        // 创建指导者并传入残疾人建造者
        Director disabledDirector = new Director(disabledBuilder);

        // 构建正常人类
        Human normalHuman = normalDirector.createHuman();
        System.out.println("正常人类构建完成");

        // 构建残疾人
        Human disabledHuman = disabledDirector.createHuman();
        System.out.println("残疾人构建完成");
    }

在Spring框架中的应用

建造者模式在Spring框架中有多种应用场景:

  1. BeanDefinitionBuilder:用于构建BeanDefinition对象,提供了流畅的API来配置bean的各种属性

    BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MyBean.class);
    builder.addPropertyValue("name", "testBean");
    builder.setScope(BeanDefinition.SCOPE_SINGLETON);
    BeanDefinition beanDefinition = builder.getBeanDefinition();
    
  2. MockMvcBuilders:在Spring测试框架中用于构建MockMvc实例

    MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
        .addFilter(new CharacterEncodingFilter("UTF-8", true))
        .build();
    
  3. UriComponentsBuilder:用于构建URI组件

    UriComponents uriComponents = UriComponentsBuilder
        .fromPath("/api/users")
        .queryParam("name", "John")
        .queryParam("age", 30)
        .build();
    
  4. ResponseEntityBuilder:用于构建HTTP响应实体

    ResponseEntity<String> response = ResponseEntity
        .status(HttpStatus.OK)
        .header("Content-Type", "application/json")
        .body("{\"message\": \"success\"}");
    

总结

建造者模式通过将复杂对象的构建过程分解为多个步骤,使得相同的构建过程可以创建不同的表示。它特别适用于那些具有复杂内部结构、需要多个步骤构建、且构建过程相对稳定的对象。在Spring框架中,建造者模式被广泛应用于各种配置和构建场景,提供了清晰、流畅的API来创建复杂对象。

posted @ 2025-08-30 16:27  庞去广  阅读(14)  评论(0)    收藏  举报