参考源
https://www.bilibili.com/video/BV1mc411h719?p=5&vd_source=299f4bc123b19e7d6f66fefd8f124a03
建造者模式(Builder Pattern)属于创建型模式
建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。
经常使用的 StringBuiler 就是建造者模式的典型实现。
普通实现
先来看下建造者模式的普通实现。
这里模拟快餐店点餐场景:
1、定义快餐食品
/*** 快餐食品(产品)*/public class Product {/*** 快餐 A 默认为汉堡*/private String BuildA = "汉堡";/*** 快餐 B 默认为可乐*/private String BuildB = "可乐";/*** 快餐 C 默认为薯条*/private String BuildC = "薯条";/*** 快餐 D 默认为甜点*/private String BuildD = "甜点";public String getBuildA() {return BuildA;}public void setBuildA(String buildA) {BuildA = buildA;}public String getBuildB() {return BuildB;}public void setBuildB(String buildB) {BuildB = buildB;}public String getBuildC() {return BuildC;}public void setBuildC(String buildC) {BuildC = buildC;}public String getBuildD() {return BuildD;}public void setBuildD(String buildD) {BuildD = buildD;}@Overridepublic String toString() {return "Product{" +"BuildA='" + BuildA + '\'' +", BuildB='" + BuildB + '\'' +", BuildC='" + BuildC + '\'' +", BuildD='" + BuildD + '\'' +'}';}}
2、定义厨房
/*** 厨房(建造者)*/public abstract class Kitchen {/*** 制作快餐 A* @param msg 快餐名称* @return 快餐*/abstract Kitchen builderA(String msg);/*** 制作快餐 B* @param msg 快餐名称* @return 快餐*/abstract Kitchen builderB(String msg);/*** 制作快餐 C* @param msg 快餐名称* @return 快餐*/abstract Kitchen builderC(String msg);/*** 制作快餐 D* @param msg 快餐名称* @return 快餐*/abstract Kitchen builderD(String msg);/*** 获取产品* @return 产品*/abstract Product getProduct();}
3、定义服务员
/*** 服务员(传递者)*/public class Waiter extends Kitchen {private Product product;public Waiter(){product = new Product();}@OverrideKitchen builderA(String msg) {product.setBuildA(msg);return this;}@OverrideKitchen builderB(String msg) {product.setBuildB(msg);return this;}@OverrideKitchen builderC(String msg) {product.setBuildC(msg);return this;}@OverrideKitchen builderD(String msg) {product.setBuildD(msg);return this;}@OverrideProduct getProduct() {return product;}}
4、客人点餐
// 叫服务员Waiter waiter = new Waiter();// 可以选择套餐,省事,直接告诉服务员要套餐即可Product product1 = waiter.getProduct();System.out.println(product1);// 也可以自己点餐,点了哪些上哪些Product product2 = waiter.builderA("炸鸡").builderB("雪碧").builderC(null).builderD(null).getProduct();System.out.println(product2);
输出结果为:
Product{BuildA='汉堡', BuildB='可乐', BuildC='薯条', BuildD='甜点'}Product{BuildA='炸鸡', BuildB='雪碧', BuildC='null', BuildD='null'}
如果选择套餐,就按照套餐默认的快餐食品送餐。
如果自己点餐,就按照点的送餐,点了哪些上哪些。
指挥者实现
在工地建筑时,除了建造本身,建造的顺序也非常重要,因此工地上一般都会有一个指挥者来决定建造的顺序。
1、定义一栋楼(产品)
/*** 一栋楼(产品)*/public class Product {/*** 地基*/private String productA;/*** 主体*/private String productB;/*** 粉刷*/private String productC;/*** 绿化*/private String productD;public String getProductA() {return productA;}public void setProductA(String productA) {this.productA = productA;}public String getProductB() {return productB;}public void setProductB(String productB) {this.productB = productB;}public String getProductC() {return productC;}public void setProductC(String productC) {this.productC = productC;}public String getProductD() {return productD;}public void setProductD(String productD) {this.productD = productD;}@Overridepublic String toString() {return "Product{" +"productA='" + productA + '\'' +", productB='" + productB + '\'' +", productC='" + productC + '\'' +", productD='" + productD + '\'' +'}';}}
2、定义包工头(抽象建造者)
/*** 包工头(抽象建造者)* @author yifan*/public abstract class Builder {/*** 打地基*/abstract void buildA();/*** 建主体*/abstract void buildB();/*** 去粉刷*/abstract void buildC();/*** 搞绿化*/abstract void buildD();/*** 建一栋楼* @return 一栋楼*/abstract Product getProduct();}
3、定义工人(实际建造者)
/*** 工人(实际建造者)*/public class Worker extends Builder{private Product product;public Worker() {// 指定要建设的楼product = new Product();}@Overridevoid buildA() {product.setProductA("地基");System.out.println("地基");}@Overridevoid buildB() {product.setProductB("主体");System.out.println("主体");}@Overridevoid buildC() {product.setProductC("粉刷");System.out.println("粉刷");}@Overridevoid buildD() {product.setProductD("绿化");System.out.println("绿化");}@OverrideProduct getProduct() {return product;}}
4、定义施工调度员(指挥者)
/*** 施工调度员(指挥者)*/public class Director {/*** 指挥包工头按照顺序建楼* @param builder 包工头* @return 楼*/public Product build(Builder builder){builder.buildA();builder.buildB();builder.buildC();builder.buildD();return builder.getProduct();}}
5、测试
// 施工调度员指挥包工头,包工头找到具体的工人按照施工调度员指定的顺序建造new Director().build(new Worker());
这样就用代码实现了工地上各岗位的协作,如果工程需要调整建造顺序,只需要更改指挥者的 build 方法即可,非常方便。
设计模式的思想起源于建筑行业,从建造者模式这里就能体现得淋漓尽致。
