代码的建筑师——使用建造者模式构建优雅的对象
编写代码时,我们通常会有一些对象的构建是非常复杂的,我们的代码可能会非常的繁琐,以至于难以理解和维护。今天我想分享的
建造者模式就是解决这一大问题的利器,通过这篇文章,我们将学习如何成为代码的建造师,构建出优雅、灵活的对象实例。
1. 概述
建造者模式是一种较为复杂的创建型模式,它将一个复杂对象的构建与表示分离开来,使得同样的构建过程可以创建不同的表现。客户端无须知道对象的内部组成以及创建的具体细节。
2. 结构
- Builder:
抽象建造者为创建一个产品对象的各个部件指定抽象接口,一般声明两类方法,一类是buildPartX(),用于创建复杂对象的部件,另一类是getResult(),用于返回创建的复杂对象; - ConCreteBuilder:
具体建造者实现了抽象建造者,实现了具体的各个部件的构造和装配方式; - Product:
产品角色就是被创建的复杂对象,包含多个组件组成。产品类通常包含设置和获取各个部件的方法; - Director:
指挥者又成为导演类,负责使用建造者构建产品,不直接创建产品实例,而是委托给具体的建造者执行构建过程。提供一个构建产品的方法,这个方法包含了构建产品所需的所有步骤;
3. 案例分析
假我们需要生产电脑,我们来使用建造者模式创建一个笔记本电脑。
产品类:(电脑就是复杂对象,电脑类中包含了许多的组件)
public class Computer {
private String cpu;
private String ram;
private String storge;
private String graphicsCard;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getRam() {
return ram;
}
public void setRam(String ram) {
this.ram = ram;
}
public String getStorge() {
return storge;
}
public void setStorge(String storge) {
this.storge = storge;
}
public String getGraphicsCard() {
return graphicsCard;
}
public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + ''' +
", ram='" + ram + ''' +
", storge='" + storge + ''' +
", graphicsCard='" + graphicsCard + ''' +
'}';
}
}
抽象建造者:(抽象建造者中定义了build组件的方法和获取复杂对象的方法)
public abstract class ComputerBuilder {
abstract void buildCpu();
abstract void buildRam();
abstract void buildStorage();
abstract void buildGraphicsCard();
abstract Computer getComputer();
}
具体建造者:(实现了抽象建造类中定义的方法,细化具体的建造组件的过程并且提供了返回复杂对象的方式)
// 具体建造者 —— 笔记本电脑
public class LaptopBuilder extends ComputerBuilder{
private Computer computer;
public LaptopBuilder() {
this.computer = new Computer();
}
@Override
public void buildCpu() {
this.computer.setCpu("Intel Core i5");
}
@Override
public void buildRam() {
this.computer.setRam("8GB DDR4");
}
@Override
public void buildStorage() {
this.computer.setStorge("256GB SSD");
}
@Override
public void buildGraphicsCard() {
this.computer.setGraphicsCard("Integrated Graphics");
}
@Override
public Computer getComputer() {
return computer;
}
}
导演类:(construct方法用于使用一定的方式创建给具体复杂对象增加功能)
public class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder computerBuilder) {
builder = computerBuilder;
}
public Computer construct() {
builder.buildCpu(); // 先建造cpu
builder.buildRam(); // 建造RAM
builder.buildStorage(); // 建造存储器
builder.buildGraphicsCard(); // 建造显卡
return builder.getComputer();
}
}
Client:
public class Client {
public static void main(String[] args) {
// 创建一个笔记本电脑的建造者
ComputerBuilder laptopBuilder = new LaptopBuilder();
// 创建一个导演
ComputerDirector computerDirector = new ComputerDirector(laptopBuilder);
// 导演开始创建笔记本
Computer laptopComputer = computerDirector.construct();
// 获取笔记本电脑
System.out.println(laptopComputer);
}
}
如果我们这个时候想要创建一个台式电脑,我们只需要新增一个具体的建造者对象就好啦~
// 具体建造者 —— 台式电脑
public class DesktopBuilder extends ComputerBuilder{
private Computer computer;
public DesktopBuilder() {
this.computer = new Computer();
}
@Override
public void buildCpu() {
this.computer.setCpu("AMD Ryzen 7");
}
@Override
public void buildRam() {
this.computer.setRam("16GB DDR4");
}
@Override
public void buildStorage() {
this.computer.setStorge("1TB HDD");
}
@Override
public void buildGraphicsCard() {
this.computer.setGraphicsCard("NVIDIA GeForce GTX 1660");
}
@Override
public Computer getComputer() {
return computer;
}
}
public class Client {
public static void main(String[] args) {
// 创建一个笔记本电脑的建造者
ComputerBuilder laptopBuilder = new LaptopBuilder();
// 创建一个导演
ComputerDirector computerDirector = new ComputerDirector(laptopBuilder);
// 导演开始创建笔记本
Computer laptopComputer = computerDirector.construct();
// 获取笔记本电脑
System.out.println(laptopComputer);
// 创建一个台式电脑的建造者
ComputerBuilder desktopBuilder = new DesktopBuilder();
// 交给导演开始建造
computerDirector = new ComputerDirector(desktopBuilder);
// 获取台式电脑
Computer desktopComputer = computerDirector.construct();
System.out.println(desktopComputer);
}
}
4. UML图
5. 优点和缺点
5.1 优点
- 分布构建: 建造者模式可以逐步的构建一个复杂的对象。客户端代码可以根据需要调用不同的建造者方法构建不同的部分,实现分布构建;
- 可配置: 可以根据需要配置产品的构建过程。不同的建造者可以根据不同的方式构建产品,建造者之间相互独立,可以很方便的新增建造者对象,获得不同的产品对象;
- 隐藏创建复杂性: 客户端创建复杂对象时,你需要了解产品的具体构建过程。隐藏了产品构建的复杂性,使客户端更加简洁;
- 对象构建灵活: 建造者模式可以在不影响其他部分的情况下更改产品的内部表示。更改产品的构建过程无须更改客户端代码;
5.2 缺点
- 不适合差异大的产品: 建造者模式创建的产品一般都有很多共同点,内部组成部分相似。如果想要创建的产品之间差异较大,就不适合使用建造者模式;
- 增加代码复杂性: 建造者模式会引入额外的类,增加了代码的复杂性;
6. 使用场景
- 构建复杂场景: 需要生成的产品内部结构复杂,通常包含多个成员变量时,建造者模式很有用,可以灵活管理对象构建过程;(写代码时构造器参数过多~~)
- 变化频繁的对象构建: 如果对象的构建过程经常发生变化,可以根据不同的需求定制产品;
- 创建不同形式的产品: 如果需要创建各种形式的产品,他们的制造过程相似且差异不大时;