文章目录
建造者模式属于创建型模式,它提供了一种创建对象的最佳方式
- 定义
- 将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示
- 作用
- 在用户不知道 对象构造过程和细节 的情况下就可以直接创建复杂的对象
- 用户只需要给出指定复杂对象的类型和内容,建造者模式负责按照顺序建造复杂对象(隐藏内部建造过程和细节)
1、角色分析
实现构造和表示相分离
2、造房子Demo
- 包含五部分
- 抽象的创建者
Builder
:抽象出构造步骤- 具体的打工人
Worker
:封装构造细节- 核心指挥者
Director
:随心所欲的构造过程- 获得的产品
Product
:产品的表示
2.1、Builder
// 抽象的建造者:不负责建房子,只提供建房子的方法
public abstract class Builder {
abstract void buildFirst(); // 第一步
abstract void buildSecond(); // 第二步
abstract void buildThird(); // 第三步
abstract void buildFourth(); // 第四步
abstract Product getProduct(); // 完活,产出产品
}
2.2、Worker
// 打工人
public class Worker extends Builder{
private Product product;
public Worker() {
product = new Product();
}
@Override
void buildFirst() {
product.setBuildFirst("先这样");
System.out.println("先这样");
}
@Override
void buildSecond() {
product.setBuildSecond("再这样");
System.out.println("再这样");
}
@Override
void buildThird() {
product.setBuildThird("然后这样");
System.out.println("然后这样");
}
@Override
void buildFourth() {
product.setBuildFourth("最后这样");
System.out.println("最后这样");
}
@Override
Product getProduct() {
return product;
}
}
2.3、Director
// 指挥(小头头):核心,负责指挥构建一个产品,产品如何构建,由他来决定
public class Director {
// 指挥工人按顺序构造产品
public Product build(Builder builder){
builder.buildFirst();
builder.buildSecond();
builder.buildThird();
builder.buildFourth();
return builder.getProduct();
}
}
2.4、Product
// 产品
@Data
public class Product {
private String buildFirst; // 第一步
private String buildSecond; // 第二步
private String buildThird; // 第三步
private String buildFourth; // 第四步
}
2.5、Test
// 小头头到位
Director director = new Director();
// 指挥某打工人构造产品
Product product = director.build(new Worker());
System.out.println(product);
2.6、Result
2.7、Demo小总结
上面的例子是建造者模式的常规用法,指挥者 Director 在建造者模式中具有很重要的作用,它是指挥具体打工人如何构建产品、控制构建步骤调用的先后顺序,并向调用者返回完整的产品,但是有些时候需要简化系统结构,可以把 Director 和抽象建造者结合。
- 我们可以通过 静态内部类 的方式实现零件无序装配构造,这种方式更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,且无需改变具体的构造方式。这样就能生产出不同的复杂产品。
静态内部类实现构造者模式可参考 设计模式之建造者模式:静态内部类实现方式
3、扔掉指挥者
扔掉指挥者,可以直接获取工人获取默认套餐,也可以通过链式编程自定义套餐。
包含三部分
- 抽象的创建者
Builder
:抽象出构造步骤- 具体的打工人
Worker
:封装构造细节- 获得的产品
Product
:产品的表示
3.1、Builder
// 抽象的建造者
public abstract class Builder {
abstract Builder buildXi(String msg); // 西红柿
abstract Builder buildEgg(String msg); // 鸡蛋
abstract Builder buildMi(String msg); // 大米饭
abstract Builder buildLa(String msg); // 小辣椒
abstract Product getProduct(); // 完活,产出产品
}
3.2、Worker
public class Worker extends Builder {
private Product product;
public Worker() {
product = new Product();
}
@Override
Builder buildXi(String msg) {
product.setBuildXi(msg);
return this;
}
@Override
Builder buildEgg(String msg) {
product.setBuildEgg(msg);
return this;
}
@Override
Builder buildMi(String msg) {
product.setBuildMi(msg);
return this;
}
@Override
Builder buildLa(String msg) {
product.setBuildLa(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
3.3、Product
// 产品:套餐
@Data
public class Product {
private String buildXi = "西红柿";
private String buildEgg= "鸡蛋";
private String buildMi = "大米饭";
private String buildLa = "小辣椒";
}
3.4、Test
// 服务员已就位
Worker builder = new Worker();
// 先来一份默认套餐
System.out.println("默认套餐:\n\t" + builder.getProduct());
// 链式编程:再来一份自定义套餐
System.out.println("自选套餐(大米饭换成小米粥):\n\t" + builder.buildMi("小米粥").getProduct());
3.5、Result
4、总结
- 应用场景
- 需要生产品对象有复杂的内部结构,这些产品对象具有共性
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
- 适合一个具有较多零件(属性)的产品(对象)的创建过程
- 建造者与抽象工厂比较
- 与抽象工厂相比,建造者返回一个组装好的完整产品;抽象工厂返回一系列相关产品,这些产品位于不同的产品等级结构,构成了一个产品族
- 在抽象工厂中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象;而在建造者中,客户端可不调用建造者的相关方法,而是通过指挥者来指导如何生成产品对象,包括对象的组装过程和建造步骤,更侧重于一步步构造一个复杂对象后再返回一个完整的对象
- 如果将抽象工厂看成汽车配件生产工厂,生产一个产品族的产品,那么建造者就是一个汽车组装工厂,通过对部件的组装返回一辆完整的汽车