定义

建造者模式将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

  • 主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象
  • 用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)

3.建造者模式 - 图1
既然是建造者模式,那么我们还是继续造房吧,其实我也想不到更简单的例子。假设造房简化为如下步骤:(1)地基 (2)钢筋工程 (3)铺电线(4)粉刷。“如果”要盖一座房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。

优缺点

优点:

  • 可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象;
  • 由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合“开闭原则”;
  • 可以更加精细的控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。

    缺点:

  • 如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式;

  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解难度和运行成本。

    使用场景

  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  2. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  3. 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
  4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

    建造者模式实现方法

    产品 Product

    1. //产品,房子
    2. @Data
    3. public class Product {
    4. private String builderA;
    5. private String builderB;
    6. private String builderC;
    7. private String builderD;
    8. }

    抽象建造者 Builder

    1. //抽象的建造者:方法
    2. public abstract class Builder {
    3. abstract void builderA();//地基
    4. abstract void builderB();//钢筋工程
    5. abstract void builderC();//铺电线
    6. abstract void builderD();//粉刷
    7. //完工:得到产品
    8. abstract Product getProduct();
    9. }

    具体建造者 ConcreteBuilder(Worker)

    1. //具体的建造者:工人
    2. public class Worker extends Builder {
    3. private Product product;
    4. public Worker() {
    5. product = new Product();
    6. }
    7. @Override
    8. void builderA() {
    9. product.setBuilderA("地基");
    10. System.out.println("地基");
    11. }
    12. @Override
    13. void builderB() {
    14. product.setBuilderB("钢筋工程");
    15. System.out.println("钢筋工程");
    16. }
    17. @Override
    18. void builderC() {
    19. product.setBuilderC("铺电线");
    20. System.out.println("铺电线");
    21. }
    22. @Override
    23. void builderD() {
    24. product.setBuilderD("粉刷");
    25. System.out.println("粉刷");
    26. }
    27. @Override
    28. Product getProduct() {
    29. return product;
    30. }
    31. }

    指挥者 Director ```java //指挥:核心,负责指挥构建一个工程(顺序),工程如何构建,由它决定 public class Director {

    //指挥工人按照顺序建房子 public Product build(Builder builder){

    1. builder.builderA();
    2. builder.builderB();
    3. builder.builderC();
    4. builder.builderD();
    5. return builder.getProduct();

    } }


//测试 public class Test { public static void main(String[] args) { //指挥 Director director = new Director(); //指挥具体的工人完成产品 Product build = director.build(new Worker()); System.out.println(build.toString()); }

}

输出结果: 地基 钢筋工程 铺电线 粉刷

  1. <a name="fyBBe"></a>
  2. # 建造者模式(拓展)
  3. ![](https://cdn.nlark.com/yuque/0/2021/png/22103819/1632389240129-f64c8412-4d82-4dae-b326-2638b7304299.png#align=left&display=inline&height=295&margin=%5Bobject%20Object%5D&originHeight=295&originWidth=779&size=0&status=done&style=none&width=779)
  4. 产品Product
  5. ```java
  6. @Data
  7. Public class Product{
  8. private String BuildA ="汉堡";
  9. private String BuildB ="可乐";
  10. private String BuildC ="薯条";
  11. private String BuildD ="甜点";
  12. }

抽象建造者 Builder

  1. //抽象建造者
  2. public abstract class Builder {
  3. abstract Builder BuildA(String msg);//"汉堡";
  4. abstract Builder BuildB(String msg);//"可乐";
  5. abstract Builder BuildC(String msg);//"薯条";
  6. abstract Builder BuildD(String msg);//"甜点";
  7. abstract Product getProduct();
  8. }

具体建造者 CorecteBuilder(Worker)

  1. public class Worker extends Builder {
  2. private Product product;
  3. public Worker() {
  4. product = new Product();
  5. }
  6. //msg为指挥者告诉builder的信息
  7. @Override
  8. Builder BuildA(String msg) {
  9. product.setBuildA(msg);
  10. return this;
  11. }
  12. @Override
  13. Builder BuildB(String msg) {
  14. product.setBuildB(msg);
  15. return this;
  16. }
  17. @Override
  18. Builder BuildC(String msg) {
  19. product.setBuildC(msg);
  20. return this;
  21. }
  22. @Override
  23. Builder BuildD(String msg) {
  24. product.setBuildD(msg);
  25. return this;
  26. }
  27. @Override
  28. Product getProduct() {
  29. return product;
  30. }
  31. }

指挥者兼消费者 Director(Consumer)

  1. public class Test {
  2. public static void main(String[] args) {
  3. //服务员
  4. Worker worker = new Worker();
  5. //可以按默认走,也可以自由组合
  6. Product product = worker.BuildA("全家桶").BuildB("雪碧").BUildC("薯条").getProduct();
  7. System.out.println(product.toString());
  8. }
  9. }
  10. -----------------------------------------------------------------------------------------
  11. 运行结果:
  12. Product{BuildA='全家桶', BuildB='雪碧', BuildC='薯条', BuildD='甜点'}