设计模式——建造者模式

一、建造者模式

1.1 建造者模式的定义

建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:

Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

构建和表示的含义如下:

构建: 创建对象的过程,涉及按照一定的步骤、顺序来组合对象的各个部分,最终生成一个完整的对象。例如,构造一辆汽车包括安装发动机、安装轮胎、装配车身等步骤。论汽车的类型如何,这些基本步骤都是相同的。

表示:构建对象的具体形态或形式。不同的表示意味着通过同样的构建步骤,可以生成不同的对象形式。例如,汽车可以有不同的表示,比如一辆跑车和一辆卡车。尽管构建的过程都包括安装发动机、轮胎和车身等步骤,但不同的表示会在每个步骤中有所不同,比如跑车使用的是高性能发动机,而卡车可能使用的是大功率发动机。

同样的构建步骤所生成的对象的具体形式,可能会因构造器的不同而有所变化。

1.2 建造者模式的参与者

在建造者模式中,不同参与者的作用如下:

  • Product(产品): 复杂对象的类,表示需要创建的复杂对象, 通常包含多个部件(字段)。它是建造者模式的最终生成目标。
  • Builder(抽象建造者):定义了构建 Product 各部分的抽象接口。该接口规定了用于创建产品各个部件的方法,但并不实现这些方法。还包含一个返回最终产品对象的方法。
  • ConcreteBuilder(具体建造者):具体化了创建产品各个部件的方法,负责跟踪构建过程的状态,并最终生成产品。每个具体建造者可以创建产品的不同表示
  • Director(指挥者):指挥者类负责控制构建过程的顺序,指导 Builder 来创建产品。换句话说,它定义了构建产品的步骤顺序,确保每个步骤按特定的顺序执行。

注意,Director 和 Builder 是聚合关系, 共同协作来完成对象的创建。

在这里插入图片描述

1.3 建造者模式的优点

  • 封装性。不关注每一个具体的模型内部如何实现。
  • 便于控制细节风险。由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

1.4 建造者模式的使用场景

  • 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
  • 如果类的属性之间有一定的依赖关系或者约束条件(源自设计模式之美),那么就可以考虑使用 Builder 设计模式。
  • 产品类非常复杂,这个时候使用建造者模式非常合适。

二、普通案例

2.1 代码设计

具体工作流程为:

  • 构建:我们定义一个构造器(Builder)类,用来逐步创建复杂对象。这个类包含生成对象的多个步骤(如“安装发动机”、“安装轮胎”)。

  • 表示:我们定义不同的具体构造器(ConcreteBuilder)类,每个构造器生成一个特定的表示(如“跑车”或“卡车”)。

2.2 实现代码

本案例的实现代码位于 java-demos/builder-pattern at main · idealzouhu/java-demos (github.com)

在这里插入图片描述

三、Lombok 实现案例

Lombok 库中的注解 @Builder 可以自动创建一个实现建造者模式的类。当在类上添加@Builder注解后,Lombok会自动生成一个建造者类,可以在类的外部使用建造者模式来创建该类的实例。

实际上,仅使用建造者模式创建复杂对象时,我们有时候可能并不需要创建 Director 类, 而是在创建对象的时候手动指定产品创建步骤

3.1 @Builder 使用方法

创建一个类,使用相应注解

@Data
@Builder
public class User {
    // 用户 ID
    private String userId;

    // 用户名
    private String username;

}

public class BuilderPatternExample {
    public static void main(String[] args) {
        User user = User.builder()
                .userId("123456")
                .username("zhangsan")
                .build();
        System.out.println(user); // 返回结果为 User(userId=123456, username=zhangsan)
    }
}

3.2 @Builder 实际所作工作

查看编译后的 User 类的源码, 可以发现在内部创建了具体建造者 UserBuilder

public class User {
    private String userId;
    private String username;

    @Generated
    public static UserBuilder builder() {
        return new UserBuilder();
    }
    
    // setter,getter,equal,construct,hashCode, toString等方法
    ...
    
     @Generated
    public static class UserBuilder {
        @Generated
        private String userId;
        @Generated
        private String username;

        @Generated
        UserBuilder() {
        }

        @Generated
        public UserBuilder userId(final String userId) {
            this.userId = userId;
            return this;
        }

        @Generated
        public UserBuilder username(final String username) {
            this.username = username;
            return this;
        }

        @Generated
        public User build() {
            return new User(this.userId, this.username);
        } 
    }
}

参考资料

《设计模式之禅 (第2版)》

秒懂设计模式之建造者模式(Builder pattern) - 知乎 (zhihu.com)

Hutool如何使用Builder模式创建线程池 (yuque.com)

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值