构建者模式(Builder)
定义
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
你可能不知道他想说什么,所以我们举个栗子帮忙治疗一下。
我们先给个图:
- 图中的 Builder 是一个抽象类,他负责 抽象定义 产品(Product)的功能(类成员属性)划分。
- 而 Worker 和 Worker_0 是Builder的实现类(当然这种实现类可以有很多),负责不同情况。
- 由 Director 确定对应的方案 并 指定 Worker 去完成构造。
- 当然,应用层(也就是用户)需要借助 Director 去获取 对应的产品实例。
代码
Product
//产品
public class Product {
private String builderA;
private String builderB;
private String builderC;
private String builderD;
public String getBuilderA() {
return builderA;
}
public void setBuilderA(String builderA) {
this.builderA = builderA;
}
public String getBuilderB() {
return builderB;
}
public void setBuilderB(String builderB) {
this.builderB = builderB;
}
public String getBuilderC() {
return builderC;
}
public void setBuilderC(String builderC) {
this.builderC = builderC;
}
public String getBuilderD() {
return builderD;
}
public void setBuilderD(String builderD) {
this.builderD = builderD;
}
@Override
public String toString() {
return "Product{" +
"builderA='" + builderA + '\'' +
", builderB='" + builderB + '\'' +
", builderC='" + builderC + '\'' +
", builderD='" + builderD + '\'' +
'}';
}
}
Builder
//抽象的构造者
abstract class Builder {
//完成模块A
abstract void builderA();
//完成模块B
abstract void builderB();
//完成模块C
abstract void builderC();
//完成模块D
abstract void builderD();
//获得产品
abstract Product getProduct();
}
Director
//指挥者:负责指定 不同 Worker ,怎样定制模块套餐
public class Director {
//指定 Worker ,确认模块取舍,按照怎样的顺序 来完成此 Product
public Product build(Builder builder) {
/*
* 此方案便是 A B C D四个模块都保留,且按顺序实现
*/
builder.builderA();
builder.builderB();
builder.builderC();
builder.builderD();
return builder.getProduct();
}
}
Worker
//具体建造者
public class Worker extends Builder {
private final Product product;
//由具体建造者创造出产品
public Worker() {
this.product = new Product();
}
@Override
void builderA() {
product.setBuilderA("完成 模块A");
System.out.println("完成 模块A");
}
@Override
void builderB() {
product.setBuilderB("完成 模块B");
System.out.println("完成 模块B");
}
@Override
void builderC() {
product.setBuilderC("完成 模块C");
System.out.println("完成 模块C");
}
@Override
void builderD() {
product.setBuilderD("完成 模块D");
System.out.println("完成 模块D");
}
@Override
Product getProduct() {
return product;
}
}
User
//用户
public class User {
public static void main(String[] args) {
//找到指挥者
Director director = new Director();
//指挥者 指定 Worker 构建产品
Product product = director.build(new Worker());
System.out.println(product.toString());
}
}
完成 模块A
完成 模块B
完成 模块C
完成 模块D
Product{builderA=‘完成 模块A’, builderB=‘完成 模块B’, builderC=‘完成 模块C’, builderD=‘完成 模块D’}
Process finished with exit code 0
链式编程
这也许才是我们常见的 Builder 模式。
形似这样:
这次的设计思路有些许变化:
- 开除了 Director,这次由用户直接定制 “产品”。
- 由 Worker 提供一个默认套餐(如果用户没有定制,而是直接获取产品,这时就给他默认套餐)
代码
Product
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
Builder
//构建者
public abstract class Builder {
//模块A
abstract Builder buildA(String msg);
//模块B
abstract Builder buildB(String msg);
//模块C
abstract Builder buildC(String msg);
//模块D
abstract Builder buildD(String msg);
abstract Product getProduct();
}
Worker
public class Worker extends Builder{
protected final Product product;
public Worker() {
this.product = new Product();
// Worker 定制的默认套餐
product.setBuildA("buildA");
product.setBuildB("buildB");
product.setBuildC("buildC");
product.setBuildD("buildD");
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
User
public class User {
public static void main(String[] args) {
Worker worker = new Worker();
Product product = worker.buildA("replaceA").buildC("replaceC").getProduct();
System.out.println(product.toString());
System.out.println(worker.getProduct());
}
}
Product{buildA=‘replaceA’, buildB=‘buildB’, buildC=‘replaceC’, buildD=‘buildD’}
Product{buildA=‘replaceA’, buildB=‘buildB’, buildC=‘replaceC’, buildD=‘buildD’}
Process finished with exit code 0