1. 介绍
将一个复杂对象的表示与构建分离,使相同的构建过程可以创建不同的表示。
2. 概述
- 建造者模式是23种设计模式中的一种,属于设计模式中的创建型模式。
- 建造者模式(Builder Pattern)又称生成器模式,生成器模式可以一步步的构建复杂对象,调用者只需要指定复杂对象的类型和内容就可以创建指定复杂对象,无需关心具体创建过程。
- 建造者模式需要增加新的复杂对象时,只需要增加具体建造者即可,实现了解藕,符合开闭原则。
- 建造者模式和工厂方法模式很类似,但是工厂方法模式主要是对产品族的创建,比如有个小米工厂方法,用来创建小米手机、小米手环、小米耳机等,并不需要关心如何创建手机、手环、耳机等,这就是创建产品族。而建造者模式是对一种产品的构建,比如构造一个小米手机,需要组装cpu、摄像头、内存等,不同版本的小米手机又需要不同的cpu、摄像头、内存等。
3. 角色组成
-
产品角色(Product):一个具体的产品对象。
-
抽象建造者(Builder ):构建一个产品对象的各个组件指定的接口或抽象类。
-
具体建造者(ConcreteBuilder):实现了抽象建造者接口或抽象类,真正负责构建产品对象。
-
指挥者(Director): 指挥抽象建造者创建一个产品对象,通过指挥者隔离了产品构建和控制了产 品构建的顺序。
通俗解释:产品对象相当于一个空壳手机,抽象建造者相当于组装说明书,告诉你需要组装哪些组件,具体建造者相当于cpu、内存、电池等,指挥者相当于流水线工人,根据组装说明书组装手机
4. 应用实例
以小米手机为例,组装一个手机,需要安装cpu、内存、喇叭、听筒、按键板、摄像头、电池、外壳等。组装必然会有先后顺序,不会先组装外壳,后组装内存吧,这就是建造者模式的作用之一,我可以造小米9,也可以造小米10,只需要增加一个具体建造者并且告诉指挥者即可,废话不多说,开始编码
4.1 产品角色
/**
* 手机
* @author yz
* @version 1.0
* @date 2020/8/13 14:32
*/
public class Phone {
private String phoneName;//手机名称
private String phoneModel;//手机信号
private String cpu;//CPU
private String ram;//内存
private String speaker;//喇叭
private String camera;//摄像头
private String battery;//电池
private String shell;//外壳
//getter and setter
}
4.2 抽象建造者
/**
* @author yz
* @version 1.0
* @date 2020/8/13 15:51
* 手机抽象建造者(抽象类也可以是接口)
*/
public abstract class PhoneBuilder {
//设置手机名称
public abstract void setPhoneName();
//设置手机型号
public abstract void setPhoneModel();
//组装CPU
public abstract void buildCpu();
//组装内存
public abstract void buildRam();
//组装喇叭
public abstract void buildSpeaker();
//组装摄像头
public abstract void buildCamera();
//组装电池
public abstract void buildBattery();
//组装外壳
public abstract void buildShell();
//获取产品
public abstract Phone getPhone();
}
4.3 具体建造者
/**
* @author yz
* @version 1.0
* @date 2020/8/13 16:07
* 小米手机建造者
*/
public class XiaoMiPhoneBuilder extends PhoneBuilder{
Phone phone=new Phone();
@Override
public void setPhoneName() {
this.phone.setPhoneName("小米");
System.out.println("小米");
}
@Override
public void setPhoneModel() {
this.phone.setPhoneModel("10");
System.out.println("10");
}
@Override
public void buildCpu() {
this.phone.setCpu("高通(Qualcomm)");
System.out.println("组装Cpu-高通(Qualcomm)");
}
@Override
public void buildRam() {
this.phone.setRam("16G");
System.out.println("组装内存16G");
}
@Override
public void buildSpeaker() {
this.phone.setSpeaker("扬声器");
System.out.println("组装扬声器");
}
@Override
public void buildCamera() {
this.phone.setCamera("摄像头");
System.out.println("组装摄像头");
}
@Override
public void buildBattery() {
this.phone.setCamera("电池");
System.out.println("组装电池");
}
@Override
public void buildShell() {
this.phone.setCamera("陶瓷外壳");
System.out.println("组装陶瓷外壳");
}
@Override
public Phone getPhone() {
return phone;
}
}
/**
* @author yz
* @version 1.0
* @date 2020/8/13 16:07
* 红米手机建造者
*/
public class HongMiPhoneBuilder extends PhoneBuilder{
Phone phone=new Phone();
@Override
public void setPhoneName() {
this.phone.setPhoneName("红米");
System.out.println("红米");
}
@Override
public void setPhoneModel() {
this.phone.setPhoneModel("note9");
System.out.println("note9");
}
@Override
public void buildCpu() {
this.phone.setCpu("其他");
System.out.println("组装Cpu-其他");
}
@Override
public void buildRam() {
this.phone.setRam("4G");
System.out.println("组装内存4G");
}
@Override
public void buildSpeaker() {
this.phone.setSpeaker("扬声器");
System.out.println("组装扬声器");
}
@Override
public void buildCamera() {
this.phone.setCamera("摄像头");
System.out.println("组装摄像头");
}
@Override
public void buildBattery() {
this.phone.setCamera("电池");
System.out.println("组装电池");
}
@Override
public void buildShell() {
this.phone.setCamera("塑料外壳");
System.out.println("组装塑料外壳");
}
@Override
public Phone getPhone() {
return phone;
}
}
4.4 指挥者
/**
* @author yz
* @version 1.0
* @date 2020/8/13 16:03
* 指挥者
*/
public class Director {
/**
* 构建对象
* @param builder
* @return
*/
public Phone constructPhone(PhoneBuilder builder){
builder.setPhoneName();
builder.setPhoneModel();
builder.buildCpu();
builder.buildRam();
builder.buildSpeaker();
builder.buildCamera();
builder.buildBattery();
builder.buildShell();
System.out.println("组装完成");
return builder.getPhone();
}
}
4.5 测试
public static void main(String[] args) {
XiaoMiPhoneBuilder xiaoMiPhoneBuilder=new XiaoMiPhoneBuilder();
HongMiPhoneBuilder hongMiPhoneBuilder=new HongMiPhoneBuilder();
Director director=new Director();
//小米手机
Phone xiaoMiPhone=director.constructPhone(xiaoMiPhoneBuilder);
System.out.println();
//红米手机
Phone hongMiPhone=director.constructPhone(hongMiPhoneBuilder);
}
4.6 结果
小米
10
组装Cpu-高通(Qualcomm)
组装内存16G
组装扬声器
组装摄像头
组装电池
组装陶瓷外壳
组装完成
红米
note9
组装Cpu-其他
组装内存4G
组装扬声器
组装摄像头
组装电池
组装塑料外壳
组装完成
5. 适用场景
- 构建的产品复杂
- 存在多个成员变量
- 成员变量之间存在依赖
- 构建产品时需要指定顺序
- 相同构建过程的不同产品
6. 优点
- 将每个组件的组装拆解成多个方法,代码更加清晰。
- 因为产品的创建过程通过接口或抽象类和产品分离,只需要增加具体实现,就可以创建新的产品
7. 缺点
- 每个产品的组件必须是类似的,并且创建过程必须相同。
- 如果内部变化复杂,需要很多的具体建造者