zoukankan      html  css  js  c++  java
  • 第十三章 建造者模式(Builder)

    建造者模式的定义与特点

    1. 定义:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建出不同的表示。
    2. 特点:建造者模式可以将一个产品的内部表象和生产过程相分离,从而可以通过一个建造过程而创建出不同内部表象的产品对象。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

    如果使用建造者模式,那么用户就只需要指定建造的类型就可以得到他们,而具体的建造细节和过程就不需要知道了。

    建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。

    建造者模式的结构与实现

    1. 模式的结构
      建造者(Builder)模式的主要角色如下。
    • 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个子部件。
    • 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
    • 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
    • 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

    其结构如图所示:

    image

    1. 模式的实现

    Product:

    public class Product {
        public String partA;
        public String partB;
        public 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;
        }
    
        public void show() {
            System.out.println("该产品由" + partA + "," + partB + "," + partC + "组成");
        }
    }
    

    Builder:

    public abstract class Builder {
    
        public abstract void buildPartA();
    
        public abstract void buildPartB();
    
        public abstract void buildPartC();
    
        public abstract Product getResult();
    }
    

    ConcreteBuilder1:

    public class ConcreteBuilder1 extends Builder {
    
        private Product product;
    
        public ConcreteBuilder1() {
            product = new Product();
        }
    
        public void buildPartA() {
            product.setPartA("构建组件A");
        }
    
        public void buildPartB() {
            product.setPartB("构建组件B");
        }
    
        public void buildPartC() {
            product.setPartC("构建组件C");
        }
    
        public Product getResult() {
            return product;
        }
    }
    

    ConcreteBuilder2:

    public class ConcreteBuilder2 extends Builder {
    
        private Product product;
    
        public ConcreteBuilder2() {
            product = new Product();
        }
    
        public void buildPartA() {
            product.setPartA("构建组件AA");
        }
    
        public void buildPartB() {
            product.setPartB("构建组件BB");
        }
    
        public void buildPartC() {
            product.setPartC("构建组件CC");
        }
    
        public Product getResult() {
            return product;
        }
    }
    

    Director:

    public class Director {
    
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        /**
         * 创建Product实例
         *
         * @return
         */
        public Product construct() {
            this.builder.buildPartA();
            this.builder.buildPartB();
            this.builder.buildPartC();
    
            return this.builder.getResult();
        }
    }
    

    测试类:

    public class BuilderTest {
    
        public static void main(String[] args) {
            Builder builder1 = new ConcreteBuilder1();
    
            Director director1 = new Director(builder1);
    
            Product product1 = director1.construct();
    
            product1.show();
    
            Builder builder2 = new ConcreteBuilder2();
    
            Director director2 = new Director(builder2);
    
            Product product2 = director2.construct();
    
            product2.show();
        }
    }
    

    测试结果:

    该产品由构建组件A,构建组件B,构建组件C组成
    该产品由构建组件AA,构建组件BB,构建组件CC组成
    
    Process finished with exit code 0
    

    Builder是抽象类,定义了构建各个组件的方法,由子类去实现具体的构建方法。在Director类中调用具体实现类ConcreteBuilder的各个构建方法去组装Product的实例。

    建造模式还有另一种写法,将Director省去,在客户端调用各个组件的构造方法,由用户去决定构建产品的各个组件的细节,也就是说将Director的权力移交给了调用方。

    第二种方式的建造者类:

    public abstract class Builder2 {
    
        public abstract Builder2 buildPartA(String message);
    
        public abstract Builder2 buildPartB(String message);
    
        public abstract Builder2 buildPartC(String message);
    
        public abstract Product build();
    }
    

    和第一种方式的区别就是各个方法的返回值类型为建造者,并且组件的细节是通过参数传进去的。

    具体的建造者实现类:

    public class ConcreteBuilder3 extends Builder2 {
    
        private Product product;
    
        public ConcreteBuilder3() {
            product = new Product();
        }
    
        public Builder2 buildPartA(String message) {
            product.setPartA(message);
            return this;
        }
    
        public Builder2 buildPartB(String message) {
            product.setPartB(message);
            return this;
        }
    
        public Builder2 buildPartC(String message) {
            product.setPartC(message);
            return this;
        }
    
        public Product build() {
            return product;
        }
    }
    

    测试类:

    ublic class Builder2Test {
    
        public static void main(String[] args) {
            Builder2 builder2 = new ConcreteBuilder3();
    
            Product product = builder2.buildPartA("A组件").buildPartB("B组件").buildPartC("C组件").build();
    
            product.show();
        }
    }
    

    测试结果:

    该产品由A组件,B组件,C组件组成
    
    Process finished with exit code 0
    

    这种方式使用更加灵活,可以根据用户需求自由定义更改内容。但是也违背了用户不需要知道构建细节的定义。

    模式的应用场景

    建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。

    • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
    • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
  • 相关阅读:
    深度之眼PyTorch训练营第二期 --- 8、权值初始化
    深度之眼PyTorch训练营第二期 ---7、nn网络层--卷积层
    深度之眼PyTorch训练营第二期 ---6、nn.Module与网络模型构建
    C#数据库部分复习
    【jzoj1481】偷懒的西西
    【2020.12.03提高组模拟】黎明卿 (bondorudo)
    【2020.11.30提高组模拟】剪辣椒(chilli)
    引流
    【高精度】加减乘+组合数+比较大小(结构体)
    【易懂】费用流【SDOI2009】晨跑
  • 原文地址:https://www.cnblogs.com/liuxiany/p/12734965.html
Copyright © 2011-2022 走看看