概述
- 将一个复杂对象的构建与表示分离,拆分成不同模块进行构建。模块不同,构建过程一致,最终构建出的对象会有不同的表示(解耦,复用)。
- 比如:构建电脑,可以拆分成主机,显示器,键盘等模块,不同的主机构建出的电脑,性能会有不同的表示。
角色
- 产品(product):最终目的(电脑)
- 抽象建造者:创建规范(电脑需要哪些设备,接口规范)
- 具体建造者:具体实现(提供电脑需要的那些设备,接口实现)
- 指挥者:组装顺序步骤,指挥具体建造者去组装(组装点的具体步骤,组装出来)
实现
public class Test {
public static void main(String[] args) {
ComputerFactory computerFactory = new ComputerFactory(new HuaweiComputer());
Computer computer = computerFactory.construct();
System.out.println(computer.getHostClass());
System.out.println(computer.getMonitorClass());
}
}
class Computer {
private String hostClass;
private String monitorClass;
public String getHostClass() {
return hostClass;
}
public void setHostClass(String hostClass) {
this.hostClass = hostClass;
}
public String getMonitorClass() {
return monitorClass;
}
public void setMonitorClass(String monitorClass) {
this.monitorClass = monitorClass;
}
}
abstract class AbstractComputer {
protected Computer computer = new Computer();
abstract void loadHost();
abstract void loadMonitor();
abstract Computer createComputer();
}
class LenovoComputer extends AbstractComputer {
@Override
void loadHost() {
computer.setHostClass("联想主机");
}
@Override
void loadMonitor() {
computer.setMonitorClass("联想显示器");
}
@Override
Computer createComputer() {
return computer;
}
}
class HuaweiComputer extends AbstractComputer {
@Override
void loadHost() {
computer.setHostClass("华为主机");
}
@Override
void loadMonitor() {
computer.setMonitorClass("华为显示器");
}
@Override
Computer createComputer() {
return computer;
}
}
class ComputerFactory {
private AbstractComputer computer;
ComputerFactory(AbstractComputer computer) {
this.computer = computer;
}
public Computer construct(){
this.computer.loadHost();
this.computer.loadMonitor();
return this.computer.createComputer();
}
}
简化改进
- 有些情况下,对象不是很复杂,可以简化代码:把指挥者组合在抽象构建者中
- 但是抽象构建者违背了单一职责原则(既要构建组件,还要对组件进行组装)
- 因此:抽奖复杂对象时,建议还是要有指挥者。
public class Test {
public static void main(String[] args) {
AbstractComputer computerFactory = new LenovoComputer();
Computer computer = computerFactory.construct();
System.out.println(computer.getHostClass());
System.out.println(computer.getMonitorClass());
}
}
class Computer {
private String hostClass;
private String monitorClass;
public String getHostClass() {
return hostClass;
}
public void setHostClass(String hostClass) {
this.hostClass = hostClass;
}
public String getMonitorClass() {
return monitorClass;
}
public void setMonitorClass(String monitorClass) {
this.monitorClass = monitorClass;
}
}
abstract class AbstractComputer {
protected Computer computer = new Computer();
abstract void loadHost();
abstract void loadMonitor();
abstract Computer createComputer();
public Computer construct(){
loadHost();
loadMonitor();
return createComputer();
}
}
class LenovoComputer extends AbstractComputer {
@Override
void loadHost() {
computer.setHostClass("联想主机");
}
@Override
void loadMonitor() {
computer.setMonitorClass("联想显示器");
}
@Override
Computer createComputer() {
return computer;
}
}
class HuaweiComputer extends AbstractComputer {
@Override
void loadHost() {
computer.setHostClass("华为主机");
}
@Override
void loadMonitor() {
computer.setMonitorClass("华为显示器");
}
@Override
Computer createComputer() {
return computer;
}
}
优点
- 将复杂产品拆分成一个个细小的组件,不必知道产品内部细节和组装流程。只需提供需要的组件即可。
- 需要扩展时,只需构建一个新的建造者类。基本不用修改已有的代码。
- 良好的封装性,可维护性。低耦合,易扩展,切换组件容易。符合开闭原则。
缺点
- 产品的差异性具有较多的共同点时才适用,因此有一定的限制性。
适用场景
- 创建的对象相对复杂,组件经常会发生变化,但具体组装流程稳定。
- 组件和构建过程只为了最终产品,构建之后,最终产品与组件,构建过程独立。
模式扩展
- 开发中,构造器参数较多时或者构造器较多时,可读性差,参数易传错。可以使用建造者模式进行优化重构。
实现
public class Tets {
public static void main(String[] args) {
Computer computer = new Computer.Builder()
.host("192")
.keyboard("keyboard")
.mouse("ha")
.monitor("xianshiq")
.build();
System.out.println(computer);
}
}
class Computer {
private String host;
private String mouse;
private String monitor;
private String keyboard;
private Computer(Builder builder) {
this.host = builder.host;
this.mouse = builder.mouse;
this.monitor = builder.monitor;
this.keyboard = builder.keyboard;
}
public static final class Builder {
private String host;
private String mouse;
private String monitor;
private String keyboard;
public Builder host(String host) {
this.host = host;
return this;
}
public Builder mouse(String mouse) {
this.mouse = mouse;
return this;
}
public Builder monitor(String monitor) {
this.monitor = monitor;
return this;
}
public Builder keyboard(String keyboard) {
this.keyboard = keyboard;
return this;
}
public Computer build() {
return new Computer(this);
}
}
@Override
public String toString() {
return "Computer{" +
"host='" + host + '\'' +
", mouse='" + mouse + '\'' +
", monitor='" + monitor + '\'' +
", keyboard='" + keyboard + '\'' +
'}';
}
}
工厂方法模式对比
- 工厂方法模式注重的是整体。直接产生对象本身。
- 建造者模式注重的是过程。较复杂的对象,需要一步一步构建对象。
抽象工厂模式对比
- 抽象工厂注重的是产品族。一系列不同维度的产品,关系产品由什么工厂生产。
- 建造者模式注重的是过程。一系列过程组装构建成最终完整的产品。