建造者设计模式是一个构造复杂对象的设计模式,在一个软件系统中,可能会面临创建一个复杂对象的工作,如果使用单一的方法或者单一的对象来创建会比较烦琐,当所创建复杂对象发生改变时,整个系统就可能面临剧烈的变化。这时就需要我们将这个复杂对象的创建过程分解成若干部分,各个子部分用一定的算法构成。但是,子部分可能会经常发生变化,如何能保证整体创建工作的稳定性呢?这就需要建造者模式,建造者模式把复杂对象的创建与表示分离,使得同样的构建过程可以创建不同的表示
举个常见的例子,想必大家都买过电脑,电脑的生产或者组装其实就是属于建造者模式,我们知道,电脑的生产都需要安装CPU、内存条、硬盘等元器件。我们可以把这个安装步骤抽象出来。
1.先来创建一个Computer类
/**
* 计算机
*/
public class Computer {
private String CPU;
/*内存*/
private String memory;
/*硬盘*/
private String hardDisk;
/*键盘*/
private String keyboard;
/*鼠标*/
private String mouse;
public String getCPU() {
return CPU;
}
public void setCPU(String CPU) {
this.CPU = CPU;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getHardDisk() {
return hardDisk;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public String getKeyboard() {
return keyboard;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public String getMouse() {
return mouse;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
@Override
public String toString() {
return "Computer{" +
"CPU='" + CPU + '\'' +
", memory='" + memory + '\'' +
", hardDisk='" + hardDisk + '\'' +
", keyboard='" + keyboard + '\'' +
", mouse='" + mouse + '\'' +
'}';
}
}
2.创建一个抽象的电脑组装过程的Builder类
电脑组装一般都需要安装CPU、内存条、硬盘、键盘鼠标等,我们把这一安装过程给抽象出来
/**
* 抽象的电脑组装过程的Builder类
*/
public interface ComputerBuilder {
/**构建cpu*/
public ComputerBuilder cpu(String cpu);
/**构建内存条*/
public ComputerBuilder memory(String memory);
/**构建硬盘*/
public ComputerBuilder hardDisk(String hardDisk);
/**构建键盘*/
public ComputerBuilder keyboard(String keyboard);
/**构建鼠标*/
public ComputerBuilder mouse(String mouse);
//完成组装
public Computer build();
}
3.有了抽象的组装过程,接下来我们就需要创建具体的实现类。我们知道电脑一般都有低配版和高配版,不同配置,组装成的电脑自然就不一样
/**
* 创建一个低配版的套餐
*/
public class LowComputerBuilder implements ComputerBuilder{
private Computer computer;
public LowComputerBuilder(){
this.computer = new Computer();
}
@Override
public ComputerBuilder cpu(String cpu) {
computer.setCPU(cpu);//比如这里可扩展,可以个性化构建cpu
return this;
}
@Override
public ComputerBuilder memory(String memory) {
computer.setMemory(memory);
return this;
}
@Override
public ComputerBuilder hardDisk(String hardDisk) {
computer.setHardDisk(hardDisk);
return this;
}
@Override
public ComputerBuilder keyboard(String keyboard) {
computer.setKeyboard(keyboard);
return this;
}
@Override
public ComputerBuilder mouse(String mouse) {
computer.setMouse(mouse);
return this;
}
@Override
public Computer build() {
return computer;
}
}
/**
* 创建一个高配版的套餐
*/
public class HighComputerBuilder implements ComputerBuilder{
private Computer computer;
public HighComputerBuilder(){
this.computer = new Computer();
}
@Override
public ComputerBuilder cpu(String cpu) {
computer.setCPU(cpu);
return this;
}
@Override
public ComputerBuilder memory(String memory) {
computer.setMemory(memory);
return this;
}
@Override
public ComputerBuilder hardDisk(String hardDisk) {
computer.setHardDisk(hardDisk);
return this;
}
@Override
public ComputerBuilder keyboard(String keyboard) {
computer.setKeyboard(keyboard);
return this;
}
@Override
public ComputerBuilder mouse(String mouse) {
computer.setMouse(mouse);
return this;
}
@Override
public Computer build() {
return computer;
}
}
4.组装机者可以自由组合
public class MyClient {
public static void main(String[] args) {
//组装一个低配计算机
ComputerBuilder lowBuilder = new LowComputerBuilder();
Computer lowComputer = lowBuilder
.cpu("amd")
.memory("4G")
.hardDisk("三星128G")
.keyboard("机械键盘")
.mouse("普通鼠标")
.build();
System.out.println(lowComputer);
//组装一个高配
ComputerBuilder builder = new HighComputerBuilder();
Computer computer = builder
.cpu("inter")
.memory("16G")
.hardDisk("三星固态128G")
.keyboard("无线键盘")
.mouse("无线鼠标")
.build();
System.out.println(computer);
}
}
运行结果:
这种写法和经典建造者模式不太一样,我个人觉得这样更加灵活,可以重写任何一个零部件。传统建造者模式写法参考https://www.jianshu.com/p/afe090b2e19c;
======================================
传统建造者模式与工厂模式是极为相似的,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。
一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。