设计模式之建造者模式

作者: 无聊到学习 | 来源:发表于2020-10-05 17:55 被阅读0次

    一、简介

    在软件开发过程中如果我们要创建一个复杂的对象,这个复杂对象由多个子部件按照一定步骤组成,对象的每个组成部分是不变的,但每一部分是可以灵活选择。

    这时就可以使用建造者模式(构建模式),将对象的构造与它的表示相分离,使得相同的构建过程可以创建不同的表示(产品)。就比如:计算机都是由CPU、主板、内存、硬盘、显卡、显示器、键盘、鼠标等部件组装而成的,但对于不同种类的计算机,这些部件可能大不相同。

    建造者模式和工厂模式的关注点不同:建造者模式注重目标对象由各部件的组装过程,而工厂方法模式更注重对象的创建过程,但两者可以结合使用。

    建造者模式中主要有四类角色:
    (1)产品角色(Product)

      它是我们最终要创建的复杂对象,由具体建造者创建其各个组成部件
    

    (2)抽象建造者(Builder)

      它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 build()。
    

    (3)具体建造者(ConcreteBuilder)

    抽象建造者的实现类,完成复杂产品的各个部件的具体创建方法。
    

    (4)指挥者(Director)

    它调用建造者对象中的部件构造方法完成复杂对象的装配创建,在指挥者中不涉及具体产品的信息。
    

    建造者模式的结构图如下:


    建造者模式.JPG

    二、使用场景

    当我们想要创建的对象较复杂,由多个部件组成,对象的每个组成部分是不变的,但每一部分是可以灵活选择时,可以使用建造者模式。在StringBuilder中就用到了建造者模式,详情见扩展部分。

    它的优点在于各个具体建造者相互独立,有利于系统的扩展。且客户端不必知道产品内部组成的细节,便于控制细节风险。

    它的缺点在于产品的组成部分必须相同,这限制了其使用的范围。且如果产品的内部变化复杂,该模式会增加很多的建造者类。

    三、举例

    public class 建造者模式 {
    
       public static void main(String[] args) {
           Director dir=new Director(new ConcreteBuilder1());
           Product pro=dir.construct();
           pro.show();
       }
    
    }
    //产品角色:包含多个组成部件的复杂对象
    class Product{
       private String partA;
       private String partB;
       private String partC;
       public String getPartA() {
           return partA;
       }
       public void setPartA(String partA) {
           this.partA = partA;
       }
       public String getPartB() {
           return partB;
       }
       public void setPartB(String partB) {
           this.partB = partB;
       }
       public String getPartC() {
           return partC;
       }
       public void setPartC(String partC) {
           this.partC = partC;
       }
       public void show(){
           System.out.println("对象内部组成部分分别为:"+partA+","+partB+","+partC);
       }
    }
    //抽象建造者,包含创建产品各个子部件的抽象方法。
    abstract class Builder{
       //创建产品对象
       protected Product pro=new Product();
       public abstract Builder createPartA();
       public abstract Builder createPartB();
       public abstract Builder createPartC();
       //返回产品对象
       public Product build(){
           return pro;
       }
    }
    //具体建造者
    class ConcreteBuilder1 extends Builder{
    
       @Override
       public Builder createPartA() {
           pro.setPartA("建造partA(1)");
           return this;
       }
    
       @Override
       public Builder createPartB() {
           pro.setPartB("建造partB(1)");
           return this;
       }
    
       @Override
       public Builder createPartC() {
           pro.setPartC("建造partC(1)");
           return this;
       }
       
    }
    //指挥者:调用某个具体建造者中的方法完成复杂对象的创建
    class Director{
       private Builder builder;
       public Director(Builder builder){
           this.builder=builder;
       }
       public Product construct(){
           builder.createPartA().createPartB().createPartC();
           return builder.build();
       }
    }
    

    四、扩展

    (1) 建造者模式在应用过程中可以根据需要改变
    如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉
    抽象建造者,甚至可以省略指挥者角色。

    (2)建造者模式在 StringBuilder 中的源码分析
    StringBuilder 继承了一个 AbstractStringBuilder 类,AbstractStringBuilder 又实现了一个Appendable 接口。其中:

    • Appendable 接口定义了多个 append 方法(抽象方法),即 Appendable 为抽象建造者,定义了抽象方法

    • AbstractStringBuilder 实现了 Appendable 接口方法,这里的 AbstractStringBuilder 已经是具体建造者,只是不能实例化

    • StringBuilder 即充当了指挥者角色,同时也充当了具体的建造者,建造方法的实现是由 AbstractStringBuilder 完成,而 StringBuilder 继承了 AbstractStringBuilder,即使用的是继承复用,而不是聚合复用。

    • 存储数据的底层字符数组char[] value,可以看成产品

    五、参考

    23种设计模式——创建型设计模式(5种)
    java设计模式之构建模式
    建造者模式以及在 StringBuilder 中的应用

    相关文章

      网友评论

        本文标题:设计模式之建造者模式

        本文链接:https://www.haomeiwen.com/subject/qxmauktx.html