五、创建型(建造者模式)

建造者模式

概念
建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。


应用场景

  1. 复杂对象构建:当一个对象有多个属性,且这些属性的组合复杂时,例如配置文件的读取、复杂的界面元素等。
  2. 多个表示:需要构建的对象有不同的表示,且相同的构建过程可以生成不同的表示。
  3. 逐步构建:需要逐步构建对象,可能需要在不同的时间或不同的上下文中设置对象的属性。
  4. 不变性:当对象构建后需要保持不变的情况下,使用建造者模式可以清晰地定义对象的状态。

注意点

  • 复杂性:建造者模式适用于构建复杂对象,但如果对象较简单,可能显得过于复杂。
  • 灵活性:在构建对象时,如果需要频繁修改构建的顺序或逻辑,可能会导致建造者的实现复杂。
  • 建造者责任:建造者的职责仅限于构建过程,避免将其他逻辑混入建造者中。

核心要素

  1. 产品:最终构建的复杂对象。
  2. 建造者接口:定义构建产品的各个部分的方法。
  3. 具体建造者:实现建造者接口,负责具体的构建逻辑。
  4. 指挥者:负责调用建造者的方法,控制构建过程。

Java代码示例

// 产品
class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "Product [partA=" + partA + ", partB=" + partB + "]";
    }
}

// 建造者接口
interface Builder {
    void buildPartA();
    void buildPartB();
    Product getResult();
}

// 具体建造者
class ConcreteBuilder implements Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("Part A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Part B");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

// 指挥者
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        director.construct();

        Product product = builder.getResult();
        System.out.println(product);
    }
}

各种变形用法

  1. 使用链式方法
    可以在建造者中使用链式方法,简化代码。
// 产品
class Product {
  private String partA;
  private String partB;

  public void setPartA(String partA) {
      this.partA = partA;
  }

  public void setPartB(String partB) {
      this.partB = partB;
  }

  @Override
  public String toString() {
      return "Product [partA=" + partA + ", partB=" + partB + "]";
  }
}

// 建造者(链式方法)
class BuilderWithChain {
  private Product product = new Product();

  public BuilderWithChain buildPartA() {
      product.setPartA("Part A");
      return this;
  }

  public BuilderWithChain buildPartB() {
      product.setPartB("Part B");
      return this;
  }

  public Product build() {
      return product;
  }
}

// 客户端
public class ClientChain {
  public static void main(String[] args) {
      BuilderWithChain builder = new BuilderWithChain();
      Product product = builder.buildPartA().buildPartB().build();
      System.out.println(product);
  }
}
  1. 复杂建造者
    为不同类型的产品创建不同的建造者。
// 产品
class ComplexProduct {
    private String partA;
    private String partB;
    private String partC;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    public void setPartC(String partC) {
        this.partC = partC;
    }

    @Override
    public String toString() {
        return "ComplexProduct [partA=" + partA + ", partB=" + partB + ", partC=" + partC + "]";
    }
}

// 复杂建造者
class ComplexBuilder implements Builder {
    private ComplexProduct product = new ComplexProduct();

    @Override
    public void buildPartA() {
        product.setPartA("Complex Part A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Complex Part B");
    }

    public void buildPartC() {
        product.setPartC("Complex Part C");
    }

    @Override
    public ComplexProduct getResult() {
        return product;
    }
}

// 客户端
public class ClientComplex {
    public static void main(String[] args) {
        ComplexBuilder builder = new ComplexBuilder();
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();

        ComplexProduct product = builder.getResult();
        System.out.println(product);
    }
}
  1. 多建造者
    可以同时使用多个建造者来构建产品的不同部分。
// 产品
class MultiProduct {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "MultiProduct [partA=" + partA + ", partB=" + partB + "]";
    }
}

// 建造者接口
interface Builder {
    void buildPartA();
    void buildPartB();
    MultiProduct getResult();
}

// 具体建造者
class BuilderA implements Builder {
    private MultiProduct product = new MultiProduct();

    @Override
    public void buildPartA() {
        product.setPartA("Builder A - Part A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Builder A - Part B");
    }

    @Override
    public MultiProduct getResult() {
        return product;
    }
}

class BuilderB implements Builder {
    private MultiProduct product = new MultiProduct();

    @Override
    public void buildPartA() {
        product.setPartA("Builder B - Part A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Builder B - Part B");
    }

    @Override
    public MultiProduct getResult() {
        return product;
    }
}

// 多建造者指挥者
class MultiBuilderDirector {
    private List<Builder> builders;

    public MultiBuilderDirector(List<Builder> builders) {
        this.builders = builders;
    }

    public void constructAll() {
        for (Builder builder : builders) {
            builder.buildPartA();
            builder.buildPartB();
        }
    }
}

// 客户端
public class ClientMulti {
    public static void main(String[] args) {
        List<Builder> builders = new ArrayList<>();
        builders.add(new BuilderA());
        builders.add(new BuilderB());

        MultiBuilderDirector director = new MultiBuilderDirector(builders);
        director.constructAll();

        for (Builder builder : builders) {
            MultiProduct product = builder.getResult();
            System.out.println(product);
        }
    }
}

下面是几种建造者模式的变形用法的完整例子,展示了如何使用链式方法、复杂建造者和多建造者。

上一篇:JavaScript 命令模式实战:打造可撤销的操作命令


下一篇:如何用c++模拟创建用户(只得创建一个用户)