背景介绍
建造者模式(Builder Pattern)又叫构建者模式就是使用多个简单的对象创建一个复杂的对象,用于将一个复杂的构建与其表示分离,使得同样的构建过程可以创建不同的表示,然后通过一个Builder类(该Builder类是独立于其他对象的)创建最终的对象。建造者模式主要用于解决软件系统中复杂对象的创建问题,比如有些复杂对象的创建需要通过各部分的子对象用一定的算法构成,在需求变化时这些复杂对象将面临很大的改变,这十分不利于系统的稳定。但是,使用建造者模式能将它们各部分的算法包装起来,在需求变化后只需调整各个算法的组合方式和顺序,能极大提高系统的稳定性。建造者模式常被用于一些基本部件不会变而其组合经常变化的应用场景下。
注意,建造者模式与工厂模式的最大区别是,建造者模式更关注产品的组合方式和装配顺序,而工厂模式关注产品的生产本身(换句话说:建造者模式更注重过程,工厂模式只关注结果)。
建造者模式在设计时有以下几种角色:
- Builder:创建一个复杂产品对象的抽象接口。
- ConcreteBuilder:Builder:接口的实现类,用于定义复杂产品各个部件的装配流程。
- Product:表示被构造的复杂对象。ConcreteBuilder定义了该复杂对象的装配流程,而Product定义了该复杂对象的结构和内部表示。
- Director:构造一个使用Builder接口的对象。
实际开发中不一定都要有上面几种角色,比如Lombok实现就很简单。以生产一个电脑为例,电脑的生产包括CPU、Memory、Disk等生产过程,这些生产过程对顺序不敏感,这里的Product角色就是电脑。我们还需要定义生产电脑的Builder、ConcreteBuilder和Director。
具体实现
1:定义需要生产的产品Computer
/**
* 具体要构建的对象,这里用电脑来举例
*
* @Author: ganbo
* @Date: 2020/6/9 11:51
*/
@Data
public class Computer {
private String cpu;
private String memory;
private String disk;
}
以上代码定义了一个Computer类来描述我们要生产的产品,具体的一个Computer包括CPU、内存(memory)和磁盘(disk),当然,还包括显示器、键鼠等,这里作为demo,为简单起见就不一一列举了。
2:定义抽象接口ComputerBuilder
/**
* 定义抽象接口来描述电脑构建和装配过程
*
* @Author: ganbo
* @Date: 2020/6/9 11:52
*/
public interface ComputerBuilder {
ComputerBuilder buildCpu(String cpu);
ComputerBuilder buildMemory(String memory);
ComputerBuilder buildDisk(String disk);
Computer build();
}
以上代码定义了ComputerBuilder接口来描述电脑的组装过程,具体包括组装CPU的方法buildcpu()、组装内存的方法buildemory()和组装磁盘的方法buildDisk(),等这些都生产和组装完成后,就可以调用build()组装一台完整的电脑了。这里每个方法返回ComputerBuilder对象是为了在使用的时候支持“连式编程”。
3:定义ComputerBuilder接口实现类ComputerConcreteBuilder以实现构造和装配该产品的各个组件:
/**
* 定义ComputerBuild接口的具体实现,实现构建方法和装配电脑的各个组件
*
* @Author: ganbo
* @Date: 2020/6/9 11:55
*/
public class ComputerConcreteBuilder implements ComputerBuilder {
private Computer computer = new Computer();
public ComputerBuilder buildCpu(String cpu) {
computer.setCpu(cpu);
return this;
}
public ComputerBuilder buildMemory(String memory) {
computer.setMemory(memory);
return this;
}
public ComputerBuilder buildDisk(String disk) {
computer.setDisk(disk);
return this;
}
public Computer build() {
return computer;
}
}
以上代码定义了ComputerConcreteBuilder来完成具体电脑的组装。
4:测试
public class App {
public static void main(String[] args) {
ComputerBuilder computerBuilder = new ComputerConcreteBuilder();
Computer computer = computerBuilder
.buildCpu("Intel")
.buildMemory("三星")
.buildDisk("金士顿")
.build();
System.out.println(computer);
}
}
以上代码来测试调用ComputerBuilder接口实现电脑的组装,具体组装顺序为buildemory、buildcpu、buildDisk和buildComputer。该类是建造者模式对产品生产过程的封装,在需求发生变化且需要先装配完磁盘再装配CPU时,只需调整ComputerBuilder的执行顺序即可,每个组件的装配都稳定不变。
建造者模式在源码中的应用
在StringBuilder中,可以看到其也是使用了建造者模式:
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
BeanDefinitionBuilder也是用的建造者模式:
可以看到在设置各种属性。
MyBatis中的SqlSessionFactoryBuilder类,也是用了建造者模式,返回SqlSessionFactory对象:
通常框架里面的类似类名:XxxxBuilder类就是建造者模式里面的“建造者”。