将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
**主要解决:**主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
**使用场景:**多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又相同。因为产品类非常复杂,或者产品类中调用顺序不同产生了不同的作用。
**注意事项:**与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
角色:
在这样的设计模式中,有以下几个角色:
1、Builder(建造者):为创建一个产品对象的各个部件指定抽象接口。
2、ConcreteBuilder(具体建造者):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
3、Director(指挥者):构造一个使用Builder接口的对象,指导构建过程。
4、Product(产品):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
工作流程:
- 指挥者(Director)直接和客户(Client)进行需求沟通;
- 沟通后指挥者将客户的需求划分为各个部件的建造请求(Builder);
- 建造者(Builder)将建造请求委派到具体的建造者(ConcreteBuilder),
- ConcreteBuilder(具体建造者) 负责进行产品部件的构建,
- 最终构建成具体产品(Product);
小明去电脑城购买一套电脑配置套件,如:键盘、鼠标、显示屏、主机;
1、先定义产品抽象类,电脑 Computer.java
public abstract class Computer {
private String monitors;
private String board;
protected String os;
public void setMonitors(String monitors) {
this.monitors = monitors;
}
public void setBoard(String board) {
this.board = board;
}
public void setOs(String os) {
this.os = os;
}
@Override
public String toString() {
return "Computer{" +
"monitors='" + monitors + '\'' +
", board='" + board + '\'' +
", os='" + os + '\'' +
'}';
}
}
2、创建具体产品
public class MacComputer extends Computer{
public MacComputer() {
super.setOs("MacOS Catalina 正式版 ");
}
}
public class WinComputer extends Computer {
public WinComputer() {
super.setOs("Windows 10 专业版 ");
}
}
3、创建建造者抽象类 和具体实现类
public interface Builder {
void buildMonitors(String system);
void buildBoard(String board);
Computer build();
}
public class MacBuilder implements Builder {
Computer computer = new MacComputer();
@Override
public void buildMonitors(String monitors) {
computer.setMonitors(monitors);
}
@Override
public void buildBoard(String board) {
computer.setBoard(board);
}
@Override
public Computer build() {
return computer;
}
}
public class WinBuilder implements Builder {
Computer computer = new WinComputer();
@Override
public void buildMonitors(String monitors) {
computer.setMonitors(monitors);
}
@Override
public void buildBoard(String board) {
computer.setBoard(board);
}
@Override
public Computer build() {
return computer;
}
}
4、创建指导者Director类
public class Director {
// 组装过程
public void construct(Builder builder, String board, String monitors) {
builder.buildBoard(board);
builder.buildMonitors(monitors);
}
}
5、测试
public static void main(String[] args) {
//装机员工
Builder macBuilder = new MacBuilder();
Builder winBuilder = new WinBuilder();
//找到销售店的老板,指定装机员工
Director director = new Director();
//Mac 系统组装配置
director.construct(macBuilder,"i9级十核GTX1660Ti独显32G内存 ","飞利浦243V7 24英寸");
//开始装机
Computer computer = macBuilder.build();
//小明查看一下配置信息,防止被骗了,输出电脑信息
System.out.println(computer.toString());
//Win 系统组装配置
director.construct(winBuilder,"i7级八核GTX7450独显32G内存 ","LGD 30英寸");
//开始装机
computer = winBuilder.build();
//输出电脑信息
System.out.println(computer.toString());
}
输出:
Computer{monitors='飞利浦243V7 24英寸', board='i9级十核GTX1660Ti独显32G内存 ', os='MacOS Catalina 正式版 '}
Computer{monitors='LGD 30英寸', board='i7级八核GTX7450独显32G内存 ', os='Windows 10 专业版 '}