建造者模式
# 建造者模式
建造者模式的核心思想是将一个复杂对象的构建过程分解成多个简单的步骤,每个步骤由一个具体的建造者(Builder)负责实现。使得构建过程可控、灵活,并且与最终产品的表示相分离,提供了一种创建复杂对象的有效方式。
# 定义
通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式包含以下几个角色:
产品(Product):表示最终构建的复杂对象。产品类通常具有多个属性,需要通过建造者逐步构建而成。
抽象建造者(Abstract Builder):定义了产品的构建步骤的抽象接口。包含了创建产品各个部分的方法,如构建产品的属性、组装产品等。
具体建造者(Concrete Builder):实现了抽象建造者的接口,负责具体的产品构建过程。每个具体建造者对应一种具体的产品表示。
指挥者(Director):负责控制建造过程的顺序和调度。通过指挥者的调用,按照一定的步骤和顺序使用具体建造者来构建产品。
- img: https://bitouyun.com/images/design-pattern/builder.png
link: https://bitouyun.com/images/design-pattern/builder.png
name: 建造者模式
2
3
# 优点
将产品的构建过程与其表示分离,使得构建过程可以独立变化,而不影响最终产品的表示。
可以更加精细地控制产品的构建过程,灵活地组合各个部分,得到不同的产品表示。
可以隐藏产品的内部细节,使得构建过程对于客户端来说是透明的。
# 缺点
增加了代码复杂性:建造者模式需要定义多个角色和接口,包括产品、抽象建造者、具体建造者和指挥者等,这增加了代码的复杂性和理解难度。
增加了类的数量:为了实现建造者模式,需要创建多个类和接口,特别是当有多个具体建造者时,会导致类的数量增加,增加了代码的维护成本。
不适合创建简单对象:建造者模式主要用于创建复杂对象,如果需要创建的对象比较简单,使用建造者模式可能会显得繁琐,不是很合适。
不易扩展新的建造者:如果需要新增一种产品的具体建造者,就需要修改抽象建造者的接口,以及所有具体建造者的实现类,这可能会影响到现有代码的稳定性和扩展性。
需要全程指导:为了保证产品的正确构建,需要一个指挥者来指导建造过程,如果指挥者缺失或者错误地指导了建造过程,可能会导致产品构建失败。
# 应用场景
当需要创建复杂对象,并且对象的构建过程需要多个步骤、可灵活组合时。
当需要创建的对象具有多个属性,且属性之间存在复杂的依赖关系。
当需要隔离对象的构建过程和最终表示,并且希望通过相同的构建过程创建不同的表示。
建造者模式与工厂模式区别
目的不同:
建造者模式的主要目的是创建复杂对象,并通过一步步构建的方式来控制对象的构造过程。它关注的是如何按照一定的步骤和规则创建对象,以达到灵活组合和构建复杂对象的目的。
工厂模式的主要目的是封装对象的创建过程,并通过使用一个共同的接口或基类来统一创建不同类型的对象。它关注的是如何根据需求返回合适的对象实例,以提供对象的实例化过程的封装和解耦。
使用方式不同:
建造者模式使用一系列步骤来创建对象,客户端可以自由地指定每个步骤的执行顺序和内容,以构建不同配置的对象。
工厂模式通过一个工厂类或方法来创建对象,客户端只需要提供必要的信息,而无需关心对象的具体创建过程。
强调点不同:
建造者模式强调对象的构建过程和细节,通常涉及多个步骤和部件的组合。它适用于构建复杂对象,允许通过不同的步骤和组件来创建不同的对象配置。
工厂模式强调对象的创建过程和类型的封装,它提供了一种统一的接口或方法来创建对象,客户端只需关注所需的对象类型即可。
# 示例代码
场景:
建造者模式创建电脑
/**
* 电脑-复杂对象
*/
@Setter
@ToString
public class Computer {
/**
* 中央处理器
*/
private String cpu;
/**
* 内存
*/
private int memory;
/**
* 硬盘
*/
private int storage;
/**
* 操作系统
*/
private String operatingSystem;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 抽象电脑建造者
*/
public abstract class ComputerBuilder {
// 创建电脑
protected Computer computer;
public void createNewComputer(){
computer = new Computer();
}
// 返回电脑
public Computer getComputer(){
return computer;
}
public abstract void buildCPU();
public abstract void buildMemory();
public abstract void buildStorage();
public abstract void buildOperatingSystem();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 游戏电脑建造者-具体建造者
*/
public class GamingComputerBuilder extends ComputerBuilder {
@Override
public void buildCPU() {
computer.setCpu("Intel Core i9");
}
@Override
public void buildMemory() {
computer.setMemory(128);
}
@Override
public void buildStorage() {
computer.setStorage(10000);
}
@Override
public void buildOperatingSystem() {
computer.setOperatingSystem("Windows 11");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 办公电脑建造者-具体建造者
*/
public class OfficeComputerBuilder extends ComputerBuilder {
@Override
public void buildCPU() {
computer.setCpu("Intel Core i5");
}
@Override
public void buildMemory() {
computer.setMemory(4);
}
@Override
public void buildStorage() {
computer.setStorage(200);
}
@Override
public void buildOperatingSystem() {
computer.setOperatingSystem("Windows 7");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 电脑创建指挥者
*/
public class ComputerDirector {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer getComputer(){
return computerBuilder.getComputer();
}
// 电脑构建与组装
public void constructComputer(){
computerBuilder.createNewComputer();;
computerBuilder.buildCPU();
computerBuilder.buildMemory();
computerBuilder.buildStorage();
computerBuilder.buildOperatingSystem();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 测试类
*/
@Slf4j
public class Client {
public static void main(String[] args) {
// 建造游戏电脑
ComputerDirector computerDirector = new ComputerDirector(); // 电脑指挥者
GamingComputerBuilder gamingComputerBuilder = new GamingComputerBuilder(); // 游戏电脑建造者
computerDirector.setComputerBuilder(gamingComputerBuilder); // 设置游戏电脑建造者
computerDirector.constructComputer(); // 建造组装游戏电脑
Computer gamingComputer = computerDirector.getComputer(); // 获取游戏电脑
log.info("游戏电脑:{}",gamingComputer);
// 建造办公电脑
OfficeComputerBuilder officeComputerBuilder = new OfficeComputerBuilder(); // 办公电脑建造者
computerDirector.setComputerBuilder(officeComputerBuilder); // 设置办公电脑建造者
computerDirector.constructComputer(); // 建造组装办公电脑
Computer officeComputer = computerDirector.getComputer(); // 获取办公电脑
log.info("办公电脑:{}", officeComputer);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Make sure to add code blocks to your code group