美文网首页
04 设计模式自学笔记(Java)-建造者模式Builder[创

04 设计模式自学笔记(Java)-建造者模式Builder[创

作者: Number9527 | 来源:发表于2023-04-13 19:35 被阅读0次

    一、建造者模式的本质

    建造者模式的本质:一是封装/隐藏具体类实例对象的创建过程,这一点与工厂模式一样,因为毕竟建造者模式也是属于创建型模式;二是支持复杂对象的创建过程,同时对对象的创建过程进行灵活的定制化。

    二、建造者模式目的

    将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示,即使用同样的构建过程创建出不同的对象,这样对于客户端/使用者来说就不需要了解复杂的构建过程,只需要关注最终构建出来的对象是否满足要求即可。

    三、示例场景

    某个理财网站可提供理财产品售卖服务,用户下单后,系统后台需要生成购买人信息、理财产品合同、售卖方信息、理财经纪人信息等,按照监管部门要求,每家公司都需要先确定用户资质(即生成购买人信息,以确认资质),然后确定理财经纪人资质,然后依次生成合同和售卖方信息(这里假设为银行)。

    注意事项:1)监管部门可能对监管要求有调整;2)每家公司可能会频繁发布新产品。

    四、代码实现及对比

    产品类定义,定义了产品属性。

    public class Product {
        //具体产品类
        //产品中包含buyer和contract两个属性
        String buyer;
        String contract;
    
        public String getBuyer() {
            return buyer;
        }
    
        public void setBuyer(String buyer) {
            this.buyer = buyer;
        }
    
        public String getContract() {
            return contract;
        }
    
        public void setContract(String contract) {
            this.contract = contract;
        }
    
        @Override
        public String toString() {
            return "Product{" +
                    "buyer=" + buyer +
                    ", contract=" + contract +
                    '}';
        }
    }
    

    抽象建造者类定义,定义了建造者需要实现的具体建造方法和产出物(即具体的产品类实例对象)。

    public interface IProductBuilder {
        
        public void buildBuyer();
        public void buildContract();
        public Product getProduct();
    }
    

    具体建造者A类定义,实现了抽象建造者的建造方法。

    public class ConcreteBuilderA implements IProductBuilder {
    
        Product product = new Product();
        @Override
        public void buildBuyer() {
            product.setBuyer("Alice");
            System.out.printf( "Alice: Buyer build complete.\n");
        }
    
        @Override
        public void buildContract() {
            product.setContract("This is the contract for Alice.");
            System.out.printf( "Alice: Contract build complete.\n");
        }
    
        @Override
        public Product getProduct() {
            return product;
        }
    }
    

    具体建造者B类定义,实现了抽象建造者的建造方法。

    public class ConcreteBuilderB implements IProductBuilder {
    
        Product product = new Product();
        @Override
        public void buildBuyer() {
            product.setBuyer("Bob");
            System.out.printf( "Bob: Buyer build complete.\n");
        }
    
        @Override
        public void buildContract() {
            product.setContract("This is the contract for Bob.");
            System.out.printf( "Bob: Contract build complete.\n");
        }
    
        @Override
        public Product getProduct() {
            return product;
        }
    }
    

    指挥者类定义,针对具体建造者对象,指定了具体建造者的建造流程,通过一个建造方法实现。

    public class Director {
        //Director定义了具体建造者需要执行的建造流程
        //具体建造者按照Director定义的流程进行建造,并通过自己的getProduct()方法交付一个具体产品类对象实例给Director
        public Product build(IProductBuilder iProductBuilder){
            iProductBuilder.buildBuyer();
            iProductBuilder.buildContract();
            return iProductBuilder.getProduct();
        }
    }
    

    客户端类定义,客户端创建一个具体建造者类实例对象和一个指挥者类对象实例,然后将具体的产品建造交给指挥者类实例对象实现。

    public class Client {
        public static void main(String[] args) {
            //首先,客户端创建一个具体建造者类对象
            IProductBuilder iProductBuilder = new ConcreteBuilderA();
            //其次,客户端创建一个指挥者类对象
            Director director = new Director();
            //然后,将具体建造者对象作为参数交给指挥者类对象,由指挥者类指挥具体建造者类去完成产品对象的创建,如流程的定制等
            Product product = director.build(iProductBuilder);
            System.out.println(product);
        }
    }
    

    五、建造者模式的UML类图

    (1)UML类图

    建造者模式UML类图.png

    建造者模式中的角色如下:

    1)抽象建造者,声明在所有子类生成器中通用的产品构造步骤,如上图中的IBuilder;

    2)具体建造者:供构造过程的不同实现,也可以构造不遵循通用接口的产品,如上图中的ConcreteBuilderA和ConcreteBuilderB;

    3)产品:最终生成的产品对象,如上图中的Product;

    4)指挥者:定义调用构造步骤的顺序,这样就可以创建和复用特定的产品配置,如上图中的Director。

    (2)实现要点

    建造者模式(附说明).png

    1)抽象建造者-IBuilder,创建一个Product,提供Product响应元素的建造方法,需要提供Product对外提供的方法;

    2)具体建造者-ConcreteBuilderA和ConcreteBuilderB:根据不同的构建者实现抽象建造者定义的方法;

    3)产品-Product:需要定义最终产品的属性,也就定义了建造者可以建造的具体元素;

    4)指挥者-Director:提供Product建造流程,并根据客户端制定的具体建造者来指挥具体建造者按照流程进行Product的建造。

    此外,客户端需要创建具体建造者和指挥者,并通过指挥者的建造方法参数将具体建造者指定给指挥者。

    六、建造者模式的优缺点

    (1)优点

    • 封装性好,使用建造者模式可以使客户端不必知道产品内部组成的细节。
    • 建造者类之间相互独立,容易扩展,对系统的扩展非常有利。
    • 便于控制细节风险 由于具体的建造者类是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

    (2)缺点

    • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式,因此其使用范围受到一定的限制。
    • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解难度和运行成本。

    适用场景

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

    相关文章

      网友评论

          本文标题:04 设计模式自学笔记(Java)-建造者模式Builder[创

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