参考源

https://www.bilibili.com/video/BV1mc411h719?p=5&vd_source=299f4bc123b19e7d6f66fefd8f124a03


建造者模式(Builder Pattern)属于创建型模式

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。

经常使用的 StringBuiler 就是建造者模式的典型实现。

普通实现

先来看下建造者模式的普通实现。

这里模拟快餐店点餐场景:

1、定义快餐食品

  1. /**
  2. * 快餐食品(产品)
  3. */
  4. public class Product {
  5. /**
  6. * 快餐 A 默认为汉堡
  7. */
  8. private String BuildA = "汉堡";
  9. /**
  10. * 快餐 B 默认为可乐
  11. */
  12. private String BuildB = "可乐";
  13. /**
  14. * 快餐 C 默认为薯条
  15. */
  16. private String BuildC = "薯条";
  17. /**
  18. * 快餐 D 默认为甜点
  19. */
  20. private String BuildD = "甜点";
  21. public String getBuildA() {
  22. return BuildA;
  23. }
  24. public void setBuildA(String buildA) {
  25. BuildA = buildA;
  26. }
  27. public String getBuildB() {
  28. return BuildB;
  29. }
  30. public void setBuildB(String buildB) {
  31. BuildB = buildB;
  32. }
  33. public String getBuildC() {
  34. return BuildC;
  35. }
  36. public void setBuildC(String buildC) {
  37. BuildC = buildC;
  38. }
  39. public String getBuildD() {
  40. return BuildD;
  41. }
  42. public void setBuildD(String buildD) {
  43. BuildD = buildD;
  44. }
  45. @Override
  46. public String toString() {
  47. return "Product{" +
  48. "BuildA='" + BuildA + '\'' +
  49. ", BuildB='" + BuildB + '\'' +
  50. ", BuildC='" + BuildC + '\'' +
  51. ", BuildD='" + BuildD + '\'' +
  52. '}';
  53. }
  54. }

2、定义厨房

  1. /**
  2. * 厨房(建造者)
  3. */
  4. public abstract class Kitchen {
  5. /**
  6. * 制作快餐 A
  7. * @param msg 快餐名称
  8. * @return 快餐
  9. */
  10. abstract Kitchen builderA(String msg);
  11. /**
  12. * 制作快餐 B
  13. * @param msg 快餐名称
  14. * @return 快餐
  15. */
  16. abstract Kitchen builderB(String msg);
  17. /**
  18. * 制作快餐 C
  19. * @param msg 快餐名称
  20. * @return 快餐
  21. */
  22. abstract Kitchen builderC(String msg);
  23. /**
  24. * 制作快餐 D
  25. * @param msg 快餐名称
  26. * @return 快餐
  27. */
  28. abstract Kitchen builderD(String msg);
  29. /**
  30. * 获取产品
  31. * @return 产品
  32. */
  33. abstract Product getProduct();
  34. }

3、定义服务员

  1. /**
  2. * 服务员(传递者)
  3. */
  4. public class Waiter extends Kitchen {
  5. private Product product;
  6. public Waiter(){
  7. product = new Product();
  8. }
  9. @Override
  10. Kitchen builderA(String msg) {
  11. product.setBuildA(msg);
  12. return this;
  13. }
  14. @Override
  15. Kitchen builderB(String msg) {
  16. product.setBuildB(msg);
  17. return this;
  18. }
  19. @Override
  20. Kitchen builderC(String msg) {
  21. product.setBuildC(msg);
  22. return this;
  23. }
  24. @Override
  25. Kitchen builderD(String msg) {
  26. product.setBuildD(msg);
  27. return this;
  28. }
  29. @Override
  30. Product getProduct() {
  31. return product;
  32. }
  33. }

4、客人点餐

  1. // 叫服务员
  2. Waiter waiter = new Waiter();
  3. // 可以选择套餐,省事,直接告诉服务员要套餐即可
  4. Product product1 = waiter.getProduct();
  5. System.out.println(product1);
  6. // 也可以自己点餐,点了哪些上哪些
  7. Product product2 = waiter
  8. .builderA("炸鸡")
  9. .builderB("雪碧")
  10. .builderC(null)
  11. .builderD(null)
  12. .getProduct();
  13. System.out.println(product2);

输出结果为:

  1. Product{BuildA='汉堡', BuildB='可乐', BuildC='薯条', BuildD='甜点'}
  2. Product{BuildA='炸鸡', BuildB='雪碧', BuildC='null', BuildD='null'}

如果选择套餐,就按照套餐默认的快餐食品送餐。

如果自己点餐,就按照点的送餐,点了哪些上哪些。

指挥者实现

在工地建筑时,除了建造本身,建造的顺序也非常重要,因此工地上一般都会有一个指挥者来决定建造的顺序。

1、定义一栋楼(产品)

  1. /**
  2. * 一栋楼(产品)
  3. */
  4. public class Product {
  5. /**
  6. * 地基
  7. */
  8. private String productA;
  9. /**
  10. * 主体
  11. */
  12. private String productB;
  13. /**
  14. * 粉刷
  15. */
  16. private String productC;
  17. /**
  18. * 绿化
  19. */
  20. private String productD;
  21. public String getProductA() {
  22. return productA;
  23. }
  24. public void setProductA(String productA) {
  25. this.productA = productA;
  26. }
  27. public String getProductB() {
  28. return productB;
  29. }
  30. public void setProductB(String productB) {
  31. this.productB = productB;
  32. }
  33. public String getProductC() {
  34. return productC;
  35. }
  36. public void setProductC(String productC) {
  37. this.productC = productC;
  38. }
  39. public String getProductD() {
  40. return productD;
  41. }
  42. public void setProductD(String productD) {
  43. this.productD = productD;
  44. }
  45. @Override
  46. public String toString() {
  47. return "Product{" +
  48. "productA='" + productA + '\'' +
  49. ", productB='" + productB + '\'' +
  50. ", productC='" + productC + '\'' +
  51. ", productD='" + productD + '\'' +
  52. '}';
  53. }
  54. }

2、定义包工头(抽象建造者)

  1. /**
  2. * 包工头(抽象建造者)
  3. * @author yifan
  4. */
  5. public abstract class Builder {
  6. /**
  7. * 打地基
  8. */
  9. abstract void buildA();
  10. /**
  11. * 建主体
  12. */
  13. abstract void buildB();
  14. /**
  15. * 去粉刷
  16. */
  17. abstract void buildC();
  18. /**
  19. * 搞绿化
  20. */
  21. abstract void buildD();
  22. /**
  23. * 建一栋楼
  24. * @return 一栋楼
  25. */
  26. abstract Product getProduct();
  27. }

3、定义工人(实际建造者)

  1. /**
  2. * 工人(实际建造者)
  3. */
  4. public class Worker extends Builder{
  5. private Product product;
  6. public Worker() {
  7. // 指定要建设的楼
  8. product = new Product();
  9. }
  10. @Override
  11. void buildA() {
  12. product.setProductA("地基");
  13. System.out.println("地基");
  14. }
  15. @Override
  16. void buildB() {
  17. product.setProductB("主体");
  18. System.out.println("主体");
  19. }
  20. @Override
  21. void buildC() {
  22. product.setProductC("粉刷");
  23. System.out.println("粉刷");
  24. }
  25. @Override
  26. void buildD() {
  27. product.setProductD("绿化");
  28. System.out.println("绿化");
  29. }
  30. @Override
  31. Product getProduct() {
  32. return product;
  33. }
  34. }

4、定义施工调度员(指挥者)

  1. /**
  2. * 施工调度员(指挥者)
  3. */
  4. public class Director {
  5. /**
  6. * 指挥包工头按照顺序建楼
  7. * @param builder 包工头
  8. * @return 楼
  9. */
  10. public Product build(Builder builder){
  11. builder.buildA();
  12. builder.buildB();
  13. builder.buildC();
  14. builder.buildD();
  15. return builder.getProduct();
  16. }
  17. }

5、测试

  1. // 施工调度员指挥包工头,包工头找到具体的工人按照施工调度员指定的顺序建造
  2. new Director().build(new Worker());

这样就用代码实现了工地上各岗位的协作,如果工程需要调整建造顺序,只需要更改指挥者的 build 方法即可,非常方便。

设计模式的思想起源于建筑行业,从建造者模式这里就能体现得淋漓尽致。