+ 什么是表示:泛指对象的属性,行为等
+ 什么是构建与表示分离:其实就是使用接口来规定其行为,然后使用具体的实现类来创建对象。使用实现类来构建,使用接口来规定其表示行为(达到构建与表示分离)
+ 同样的构建过程创建不同的表示:创建的过程由接口来规范,具体创建过程的实现由子类来完成,这样不同的子类使用相同的创建过程可以创建出不同的对象;
7.2 建造者设计模式的实现
7.2.1 案例引入
我们完成某些产品的创建需要N多个步骤(创建过程复杂),这些步骤都趋向于稳定,不会变化(相同的创建过程);
例如我们在组装游戏台式机时,需要安装顶级显卡,性能一般但主频高的CPU;组装商务台式机时,只需要安装一个亮机卡,再加一个顶级CPU;但是都需要安装显卡和CPU以及一些其他部件;创建产品的步骤趋向稳定(都需要安装CPU和显卡等部件),但是需要创建不同的对象表示(游戏台式机和商务台式机);
1)UML类图如下:
2)建造者设计模式中的角色
在建造者设计模式中主要包含有4个角色:
- 1)产品(Product):要创建的复杂对象。
- 2)抽象建造者(Builder):规范要创建对象的步骤,具体的实现由具体的子类来完成。
- 3)具体建造者(ConcreteBuilder):抽象建造者的具体实现,根据不同的业务类型,来具体化创建对象的每个步骤。
- 4)指挥者(Director):调用具体建造者的每一个步骤来完成对象的创建,指挥者并不知道产品的细节;
7.2.2 代码实现
- 电脑类:
package com.pattern.demo01\_建造者设计模式;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Computer {
private String memory;
private String cpu;
private String keyBoard;
private String mouse;
}
- 抽象构建者:
package com.pattern.demo01\_建造者设计模式;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro: 抽象构建者
\*/
public abstract class Builder {
protected Computer computer=new Computer();
// 抽象每一个步骤
public abstract void addMemory();
public abstract void addCPU();
public abstract void addKeyBoard();
public abstract void addMouse();
public abstract Computer createComputer();
}
- 具体构建者-游戏台式机构建者类:
package com.pattern.demo01\_建造者设计模式;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro: 游戏台式机构建者
\*/
public class GameBuilder extends Builder {
// 实现每一个构建步骤
@Override
public void addMemory() {
computer.setMemory("添加16G内存条!");
}
@Override
public void addCPU() {
computer.setCpu("添加i5 12600K!");
}
@Override
public void addKeyBoard() {
computer.setKeyBoard("添加游戏专用机械键盘!");
}
@Override
public void addMouse() {
computer.setMouse("添加游戏专用宏鼠标!");
}
@Override
public Computer createComputer() {
return computer;
}
}
- 具体构建者-商务台式机构建者类:
package com.pattern.demo01\_建造者设计模式;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro: 商务台式机构建者类
\*/
public class BusinessBuilder extends Builder {
// 实现每一个构建步骤
@Override
public void addMemory() {
computer.setMemory("添加32G内存条!");
}
@Override
public void addCPU() {
computer.setCpu("添加i9 12900K!");
}
@Override
public void addKeyBoard() {
computer.setKeyBoard("添加办公专用双飞燕键盘!");
}
@Override
public void addMouse() {
computer.setMouse("添加办公专用双飞燕鼠标!");
}
@Override
public Computer createComputer() {
return computer;
}
}
- 指挥者类:
package com.pattern.demo01\_建造者设计模式;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro: 指挥者类
\*/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
/\*\*
\* 调用每一个步骤来完成对象的构建
\*
\* @return
\*/
public Computer construct() {
builder.addMemory();
builder.addCPU();
builder.addKeyBoard();
builder.addMouse();
return builder.createComputer();
}
}
在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
7.2.3 建造者模式的链式写法
在普通建造者模式中,创建对象的方式被固定在了Director类中,不能再改变,对于一些创建过程需要变化的对象普通建造者模式将会变得难以维护,因此在实际开发中,我们通常使用建造者模式的链式写法来简化对象的创建过程;它允许我们自己定义创建对象的过程,并最终将创建好的对象返回;
- 产品类:
package com.pattern.demo02\_链式写法;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Computer {
private String memory;
private String cpu;
private String keyBoard;
private String mouse;
}
- 构建者类:
package com.pattern.demo02\_链式写法;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
public class ComputerBuilder {
private Computer computer=new Computer();
public ComputerBuilder addMemory(String memory) {
computer.setMemory(memory);
return this;
}
public ComputerBuilder addCPU(String cpu) {
computer.setCpu(cpu);
return this;
}
public ComputerBuilder addKeyBoard(String keyBoard) {
computer.setKeyBoard(keyBoard);
return this;
}
public ComputerBuilder addMouse(String mouse) {
computer.setMouse(mouse);
return this;
}
public Computer build() {
return computer;
}
}
- 测试类:
package com.pattern.demo02\_链式写法;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
public class Demo01 {
public static void main(String[] args) {
Computer businessComputer = new ComputerBuilder()
.addMemory("16G大内存")
.addCPU("i9 12900K")
.addKeyBoard("双飞燕键盘")
.addMouse("双飞燕鼠标")
.build();
System.out.println(businessComputer);
System.out.println("---------------------");
Computer gameComputer = new ComputerBuilder()
.addMemory("16G大内存")
.addCPU("i9 12900K")
.addKeyBoard("双飞燕键盘")
.addMouse("双飞燕鼠标")
.build();
System.out.println(gameComputer);
}
}
在建造者模式的链式写法中,Demo01测试类充当了Director的角色,将创建对象的步骤灵活化;
7.2.4 静态内部类实现建造者模式
在实际开发中,我们通常会忽略对象创建的复杂性,将对象的创建过程封装好,只需要调用创建对象的某个方法即可获取对象,因此我们会更加倾向于使用工厂设计模式;工厂设计模式不存在Builder和Director。
一般情况下,使用静态内部类的方式来实现建造者模式将会变得非常轻松,这样一个产品类内部自带一个具体的创建对象,使得建造者模式的形式变得更加简洁;
- 产品类:
package com.pattern.demo03\_静态内部类;