Java设计模式 五 建造者模式 (Builder Pattern)

建造者模式 (Builder Pattern) 是一种创建型设计模式,专注于构造复杂对象的过程。它将对象的创建过程分解为多个步骤,并允许以不同的方式构造对象。

建造者模式的核心在于分离对象的构造和表示,以便相同的构造过程可以创建不同的表示。它通常用于构建复杂的对象,例如具有多个部分的对象或需要按照特定顺序创建的对象。


1. 建造者模式的结构

建造者模式由以下几个核心角色组成:

  • Builder(抽象建造者): 定义创建产品各个部分的抽象接口。
  • ConcreteBuilder(具体建造者): 实现 Builder 接口,构建并装配产品的各个部分。
  • Product(产品): 表示被构造的复杂对象。
  • Director(指挥者): 负责定义构建产品的顺序,调用建造者的具体方法来构造产品。
  • Client(客户端): 通过指挥者和建造者构建产品。

2. 建造者模式的优点

  • 构造过程分离: 客户端无需知道产品内部的构造细节,构造逻辑与表示逻辑分离。
  • 可复用性高: 通过不同的具体建造者,可以创建不同的产品。
  • 灵活性强: 可以方便地添加新的建造者,符合开闭原则。

3. 建造者模式的缺点

  • 复杂性增加: 增加了更多的类和代码量。
  • 适用性受限: 适用于构造过程复杂或产品具有多个组成部分的情况,不适用于简单对象的创建。

4. 建造者模式的实现

1) 定义产品类

产品是需要构建的复杂对象,由多个部分组成。

java 复制代码
public class Product {
    private String partA;
    private String partB;
    private String partC;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    public void setPartC(String partC) {
        this.partC = partC;
    }

    @Override
    public String toString() {
        return "Product [PartA=" + partA + ", PartB=" + partB + ", PartC=" + partC + "]";
    }
}
2) 定义抽象建造者接口

建造者定义了构造产品各部分的抽象接口。

java 复制代码
public interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
    Product getResult();
}
3) 实现具体建造者

具体建造者实现 Builder 接口,负责产品部件的具体创建。

java 复制代码
public class ConcreteBuilder implements Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("Part A from ConcreteBuilder");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Part B from ConcreteBuilder");
    }

    @Override
    public void buildPartC() {
        product.setPartC("Part C from ConcreteBuilder");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
4) 定义指挥者

指挥者定义了构造产品的顺序,依赖于建造者接口。

java 复制代码
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
5) 客户端代码

客户端通过指挥者来构建产品。

java 复制代码
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);

        Product product = director.construct();
        System.out.println(product);
    }
}

运行结果:

复制代码
Product [PartA=Part A from ConcreteBuilder, PartB=Part B from ConcreteBuilder, PartC=Part C from ConcreteBuilder]

5. 建造者模式的应用场景

  • 构造复杂对象: 当需要构建由多个部分组成的复杂对象时,使用建造者模式可以简化构造逻辑。
  • 构造过程需要灵活控制: 如果需要以不同方式构造同一个对象(如不同的顺序或参数),建造者模式非常适合。
  • 需要创建不可变对象: 如 Java 中的 StringBuilder,通过一系列方法逐步构建最终对象。

6. Java 中的典型应用

  • StringBuilder: 通过链式调用的方法逐步构建字符串。
  • DOM API: 用于逐步构建 XML 或 HTML 文档。
  • Guava 的 ImmutableList.BuilderImmutableMap.Builder 构建不可变的集合。

7. 与其他设计模式的比较

  • 与工厂模式的区别:

    • 工厂模式强调创建单个对象,通常对客户端隐藏实例化逻辑。
    • 建造者模式强调创建复杂对象,并允许分步骤构造。
  • 与抽象工厂模式的区别:

    • 抽象工厂模式主要用于创建一系列相关对象,注重产品族。
    • 建造者模式用于逐步构造一个复杂对象,注重构造过程。

8. 链式调用风格的建造者模式

现代建造者模式通常采用链式调用的方式,使代码更简洁。

示例:
java 复制代码
public class Product {
    private String partA;
    private String partB;
    private String partC;

    public static class Builder {
        private String partA;
        private String partB;
        private String partC;

        public Builder setPartA(String partA) {
            this.partA = partA;
            return this;
        }

        public Builder setPartB(String partB) {
            this.partB = partB;
            return this;
        }

        public Builder setPartC(String partC) {
            this.partC = partC;
            return this;
        }

        public Product build() {
            Product product = new Product();
            product.partA = this.partA;
            product.partB = this.partB;
            product.partC = this.partC;
            return product;
        }
    }

    @Override
    public String toString() {
        return "Product [PartA=" + partA + ", PartB=" + partB + ", PartC=" + partC + "]";
    }
}
使用:
java 复制代码
public class Client {
    public static void main(String[] args) {
        Product product = new Product.Builder()
                .setPartA("Custom PartA")
                .setPartB("Custom PartB")
                .setPartC("Custom PartC")
                .build();
        System.out.println(product);
    }
}

运行结果:

复制代码
Product [PartA=Custom PartA, PartB=Custom PartB, PartC=Custom PartC]

9. 总结

建造者模式在需要构建复杂对象时提供了一种清晰且灵活的解决方案。它可以有效分离对象的构造与表示,特别是在构建步骤繁多且需要复用的场景下,是一种非常实用的设计模式。

相关推荐
SimonKing21 小时前
你的IDEA还缺什么?我离不开的这两款效率插件推荐
java·后端·程序员
better_liang21 小时前
每日Java面试场景题知识点之-数据库连接池配置优化
java·性能优化·面试题·hikaricp·数据库连接池·企业级开发
Wpa.wk21 小时前
自动化测试环境配置-java+python
java·开发语言·python·测试工具·自动化
w***42421 小时前
springboot使用logback自定义日志
java·spring boot·logback
带刺的坐椅21 小时前
AI 应用工作流:LangGraph 和 Solon AI Flow,我该选谁?
java·python·ai·solon·flow·langgraph
北郭guo21 小时前
MyBatis框架讲解,工作原理、核心内容、如何实现【从浅入深】让你看完这篇文档对于MyBatis的理解更加深入
java·数据库·mybatis
庄宿正21 小时前
【Vue2+SpringBoot+SM2】Vue2 + Spring Boot 实现 SM2 双向非对称加密完整实战
java·spring boot·后端
Predestination王瀞潞21 小时前
Java EE开发技术(第七章:JSTL标签库)
java·java-ee
信仰_2739932431 天前
Java面试题
java·开发语言