建造者模式
概述
- 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 用户只需要指定需要建造的类型就可以得到它们,建造过程以及细节不需要知道。
- 类型:创建型
- 通俗的理解:建造者就是如何一步一步构建多个组件的对象,相同的构建过程可以创建不同的产品。
适用场景
- 适用那些流程固定但是顺序不固定的。
- 如果一个对象有非常复杂的内部结构(很多属性)
- 想把复杂对象的创建和适用分离开来
优点
- 封装性好,创建和适用分离
- 扩展性好,建造类之间独立,一定程度上解耦
缺点
- 产生多余的Builder对象
- 产品内部发生变化,建造者都要修改,成本比较大
建造者和工厂模式
- 建造者注重于方法的调用顺序,可以创建复杂的一些产品。
- 工厂模式注重于创建对象 ,创建都是一样的对象。
Coding
-
场景:到电脑城告诉小马技术员自己想组装什么类型的电脑
-
电脑类
public class Computer {
// 主机 显示器 键盘 鼠标
private String host;
private String keyboard;
private String monitor;
private String mouse;
public String getHost() {
return host;
}
public void setHost(String host) {
host = host;
}
public String getKeyboard() {
return keyboard;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public String getMonitor() {
return monitor;
}
public void setMonitor(String monitor) {
this.monitor = monitor;
}
public String getMouse() {
return mouse;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
@Override
public String toString() {
return "Computer{" +
"host='" + host + '\'' +
", keyboard='" + keyboard + '\'' +
", monitor='" + monitor + '\'' +
", mouse='" + mouse + '\'' +
'}';
}
}
- 计算机抽象的建造类
public abstract class ComputerBuilder {
public abstract void builderHost(String host);
public abstract void builderKeyboard(String keyboard);
public abstract void builderMonitor(String monitor);
public abstract void builderMouse(String mouse);
public abstract Computer makeComputer();
}
- 计算机的具体制作的实现类
public class ComputerBuilderProcess extends ComputerBuilder {
private Computer computer = new Computer();
@Override
public void builderHost(String host) {
computer.setHost(host);
}
@Override
public void builderKeyboard(String keyboard) {
computer.setKeyboard(keyboard);
}
@Override
public void builderMonitor(String monitor) {
computer.setMonitor(monitor);
}
@Override
public void builderMouse(String mouse) {
computer.setMouse(mouse);
}
@Override
public Computer makeComputer() {
return computer;
}
}
- 小马技术员类
public class XiaoMa {
private ComputerBuilder computerBuilder;
public XiaoMa(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer makeComputer(String host, String keyboard, String monitor, String mouse) {
System.out.println("开始组装电脑: "+"host = [" + host + "], keyboard = [" + keyboard + "], monitor = [" + monitor + "], mouse = [" + mouse + "]");
computerBuilder.builderHost(host);
computerBuilder.builderKeyboard(keyboard);
computerBuilder.builderMonitor(monitor);
computerBuilder.builderMouse(mouse);
return computerBuilder.makeComputer();
}
}
- 测试类
public class XiaoMa {
private ComputerBuilder computerBuilder;
public XiaoMa(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer makeComputer(String host, String keyboard, String monitor, String mouse) {
System.out.println("开始组装电脑: "+"host = [" + host + "], keyboard = [" + keyboard + "], monitor = [" + monitor + "], mouse = [" + mouse + "]");
computerBuilder.builderHost(host);
computerBuilder.builderKeyboard(keyboard);
computerBuilder.builderMonitor(monitor);
computerBuilder.builderMouse(mouse);
return computerBuilder.makeComputer();
}
}
UML
- 从图中我们可知,我们只需要告诉你具体什么类型的电脑。我不关心小马技术员如何创建。我只关心最后的结果是不是我想要的电脑。
- 这里好像按照建造者的定义小马技术员好像可以不存在。我们为什么不能直接操作建造者builder呢
建造者升级
-
上述的模式好像角色有点多,我们强行和小马技术员关联上了,而且使用方式和我们日常所见的建造者有点不一样,是不是。那我们在上述的版本中在升级一个版本。
-
代码如下所示:
public class Computer {
private String host;
private String keyboard;
private String monitor;
private String mouse;
public Computer(ComputerBuilder ComputerBuilder) {
this.host = ComputerBuilder.host;
this.keyboard = ComputerBuilder.keyboard;
this.monitor = ComputerBuilder.monitor;
this.mouse = ComputerBuilder.mouse;
}
@Override
public String toString() {
return "Computer{" +
"host='" + host + '\'' +
", keyboard='" + keyboard + '\'' +
", monitor='" + monitor + '\'' +
", mouse='" + mouse + '\'' +
'}';
}
/**
* 匿名内容类 负责构建计算器
*/
public static class ComputerBuilder {
private String host;
private String keyboard;
private String monitor;
private String mouse;
/**
* 返回也是 ComputerBuilder 可以链式调用
*/
public ComputerBuilder builderHost(String host) {
this.host = host;
return this;
}
public ComputerBuilder builderKeyboard(String keyboard) {
this.keyboard = keyboard;
return this;
}
public ComputerBuilder builderMonitor(String monitor) {
this.monitor = monitor;
return this;
}
public ComputerBuilder builderMouse(String mouse) {
this.mouse = mouse;
return this;
}
/**
* 组装
*/
public Computer build() {
return new Computer(this);
}
}
}
- 测试类
public class Test {
public static void main(String[] args) {
Computer computer = new Computer.ComputerBuilder().builderHost("联想主机")
.builderKeyboard("海盗船键盘")
.builderMonitor("三星显示器")
.builderMouse("小米鼠标")
.build();
System.out.println(computer.toString());
}
}
- 这样看起来是不是很熟悉,我们的链式调用,build进行创建。接下来我们再看看UML图
- 通过图示我们可知:
- ComputerBuilder 具体的计算器组装者
- Client只需要控制 ComputerBuilder 来创建自己所需要的计算机
- 如果文章有帮助到你欢迎关注微信公众号《后端学长》