一、构建者模式是什么?
在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。
以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。
构建者模式 (Builder Pattern):
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。
它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
这属于创建型模式。
二、为什么要使用构建者模式 ?
作用:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
三、构建者模式应用场景有哪些 ?
- 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。
- JAVA 中的 StringBuilder。
- Lombok 中 @Build 注解。
四、如何实现构建者模式?
模式的结构
1. 抽象产品类 Computer。
2. Builder 抽象 Builder,规范产品的组建,一般是由子类实现具体的组建过程。
3. MacbookBuilder 具体的 Builder 类,具体的创建对象的类。
4. Directror(监督者) 统一组建过程。
6. 案例 1:组装一台计算机为主
以组装一台计算机为主,主要进行组装主机,设置操作系统,设置显示器。
1. 计算机抽象类 Computer
- 抽象出计算机共同属性和行为:主板、显示器、操作系统
java
package com.computer.abstracts;
import lombok.ToString;
/**
* description: 计算机(抽象产品类)
* date: 2020/9/10 16:51
* author: Calvino
* version: 1.0
*/
@ToString
public abstract class Computer {
public Computer() {
}
/**
* 主机
*/
protected String board;
/**
* 显示器
*/
protected String display;
/**
* 操作系统
*/
protected String os;
/**
* 设置主机
*
* @param board 主机
*/
public void setBoard(String board) {
this.board = board;
}
/**
* 设置显示器
* @param display 显示器
*/
public void setDisplay(String display) {
this.display = display;
}
/**
* 设置操作系统
*/
public abstract void setOs();
}
2. 具体产品类 MacBookServiceImpl、WindowsBookSeriveImpl
- 不同的计算机继承父类,实现不同的操作系统。
java
package com.computer.service.impl;
import com.computer.abstracts.Computer;
/**
* description: 苹果电脑-具体实现类
* date: 2020/9/10 16:55
* author: Calvin
* version: 1.0
*/
public class MacBookServiceImpl extends Computer {
@Override
public void setOs() {
os = "Mac OS X 12";
System.out.println(os);
}
}
java
package com.computer.service.impl;
import com.computer.abstracts.Computer;
/**
* description: Window电脑-具体实现类
* date: 2020/9/10 16:55
* author: Calvin
* version: 1.0
*/
public class WindowsBookServiceImpl extends Computer {
@Override
public void setOs() {
os = "Windows 10";
System.out.println(os);
}
}
3. 抽象 Builder
- 规范产品的组建
java
package com.computer.abstracts;
/**
* description: Builder
* date: 2020/9/10 17:03
* author: Calvin
* version: 1.0
*/
public abstract class Builder {
/**
* 构建主机
* @param board 主机
*/
public abstract void buildBoard(String board);
/**
* 构建显示器
* @param display 显示器
*/
public abstract void buildDisplay(String display);
/**
* 构建操作系统
*/
public abstract void buildOs();
/**
* 整体主装
* @return 完整的计算机
*/
public abstract Computer build();
}
4. 具体的 Builder 类有 MacBookBuilder、WindowsBookBuilder
- 实现规范产品的组建具体过程。
java
package com.computer.builder;
import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.service.impl.MacBookServiceImpl;
/**
* description: MacBookBuilder
* date: 2020/9/10 17:07
* author: Calvin
* version: 1.0
*/
public class MacBookBuilder extends Builder {
private Computer computer;
public MacBookBuilder (){
computer = new MacBookServiceImpl();
}
@Override
public void buildBoard(String board) {
computer.setBoard(board);
}
@Override
public void buildDisplay(String display) {
computer.setDisplay(display);
}
@Override
public void buildOs() {
computer.setOs();
}
@Override
public Computer build() {
return computer;
}
}
java
package com.computer.builder;
import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.service.impl.MacBookServiceImpl;
/**
* description: MacBookBuilder
* date: 2020/9/10 17:07
* author: Calvin
* version: 1.0
*/
public class MacBookBuilder extends Builder {
private Computer computer;
public MacBookBuilder (){
computer = new MacBookServiceImpl();
}
@Override
public void buildBoard(String board) {
computer.setBoard(board);
}
@Override
public void buildDisplay(String display) {
computer.setDisplay(display);
}
@Override
public void buildOs() {
computer.setOs();
}
@Override
public Computer build() {
return computer;
}
}
5. Director 类,负责具体的构造 Computer
- Directror(监督者) 统一组建过程。
java
package com.computer.builder;
import com.computer.abstracts.Builder;
/**
* description: Director
* date: 2020/9/10 17:22
* author: Calvin
* version: 1.0
*/
public class Director {
Builder builder = null;
/**
* 初始化构造函数
* @param builer 构建抽象类
*/
public Director(Builder builer) {
this.builder = builer;
}
/**
* 统一组建构建:主机、显示器、操作系统
* @param board 主机
* @param display 显示器
*/
public void construct(String board,String display){
builder.buildDisplay(display);
builder.buildBoard(board);
builder.buildOs();
}
}
6. 具体调用过程
- 根据请求 OS 参数,获取对应的 Buidler 组建过程。
- 再通过具体的 Builder, 通过使用 Director 监督者进行组装。
- 最后,组装完成,通过 Builder 中的 build 方法,获取到主装后的完整计算机。
java
package com.computer.service.impl;
import com.computer.abstracts.Builder;
import com.computer.abstracts.Computer;
import com.computer.builder.Director;
import com.computer.enumeration.ComputerBuildEnum;
import com.computer.service.ComputerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* description: ComputerServiceImpl
* date: 2020/9/10 17:29
* author: Calvin
* version: 1.0
*/
@Slf4j
@Service
public class ComputerServiceImpl implements ComputerService {
@Override
public Computer build(String os) {
Computer computer = null;
try {
ComputerBuildEnum computerBuildEnum = ComputerBuildEnum.valueOf(os);
String builderBeanName = computerBuildEnum.getBuilderBeanName();
Class<?> builderClass = Class.forName(builderBeanName);
Builder builder = (Builder) builderClass.newInstance();
// 1. 实例监督者,进行组装电脑
Director director = new Director(builder);
director.construct("英特尔主板","Retina显示器");
// 2. 组装后,通过构建者获取对应的电脑
computer = builder.build();
} catch (Exception e) {
log.error("错误的原因:{}", e.getMessage());
throw new RuntimeException("没有该" + os + "操作系统");
}
return computer;
}
}
7. 演示测试
1. 通过访问
GET http://localhost:8080/computer/build?os=MAC_BUILD
GET http://localhost:8080/computer/build?os=WINDOWS_BUILD
2. 输出结果
verilog
Computer(board=英特尔主板, display=Retina显示器, os=Mac OS X 12)
Computer(board=英特尔主板, display=Retina显示器, os=Windows 10)