设计模式四--秒懂建造者模式

设计模式四--建造者模式

前言

        设计模式的本质在于抽象、解耦,用抽象来隔离变化。将复杂的事务按照六大设计原则,分解成一个个单一职责的个体。换而言之,是个体的高内聚和简单化,然后再组合到一起完成职能。合理使用设计模式,可以使程序设计更加标准化、代码编制更加工程化,使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

        上一篇文章中,我们已经聊完了GOF23中的第三个模式——抽象工厂模式,如果没有看过的,可以回顾一下。

创建型模式的工作原理

        创建型模式提供了一种创建对象的机制,抽象实例化的过程,隐藏了对象的创建细节,对外只提供一个通用接口,能够提升已有代码的灵活性和可复⽤性。创建型模式有五种:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。本文带着大家重新学习第四种设计模式——建造者模式(Builder Pattern)。

建造者模式

场景需求

        墨菲定律中提到:任何事都没有表面看起来的那么简单。无论在现实生活中还是在代码世界中,都存在一些复杂的对象,他们由多个部分组成,每个部分各具功能,协同运作。比如手机包含摄像头、CPU、电池等各种零部件。对于大部分用户而言,无须知道部件之间的组装细节,也几乎不会单独使用某个零部件,而是使用一部完整的手机。如果需要详细关注一个产品部件的生产、安装步骤,可以选择建造者模式对其进行设计与描述,将部件和其组装过程分开,分步创建一个复杂的对象。由于组装部件的过程复杂,因此,装配过程被分离到一个称作建造者的对象里,建造者返回给上层一个完整产品,而无须关心该产品的构建细节,这就是建造者模式的核心思想。

模式定义

        建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:

        Separate the construction of a complex object from its representation so that the same

construction process can create different representations.

        将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。那建造者模式与工厂方法模式、抽象工厂模式有什么区别呢?大家可以思考一下,后续我会详细介绍。

最佳实践

以下情况建议使用建造者模式:

1、某个对象有复杂的内部结构,通常包含多个成员属性,而且属性是可选的。

2、相同的方法,不同的执行顺序,产生不同的对象或不同的运行结果。

3、当创建一个对象需要很多步骤时,适合使用建造者模式。

针对第一种情况,产品的属性过多时,我们可以采用链式构造去解决这样的问题,代码如下:

@Data
public class Phone {

    private String cpu;//cpu必须有
    private String battery;//电池必须有
    private String camera;//摄像头可选
    private String keyboard;//按键可选

    private Phone(Builder builder) {
        this.cpu = builder.cpu;
        this.battery = builder.battery;
        this.camera = builder.camera;
        this.keyboard = builder.keyboard;
    }

    public static class Builder {
        private String cpu;//cpu必须有
        private String battery;//电池必须有
        private String camera;//摄像头可选
        private String keyboard;//按键可选

        public Builder(String cup, String battery) {
            this.cpu = cup;
            this.battery = battery;
        }

        public Builder setCamera(String camera) {
            this.camera = camera;
            return this;
        }

        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }

        public Phone build() {
            return new Phone(this);
        }
    }
}

创建产品代码

public static void main(String[] args) {
    Phone phone = new Phone.Builder("CPU", "电池")
            .setKeyboard("按键")
            .setCamera("摄像头")
            .build();
}

建造者模式通用的类图

 

建造者模式中,通常有如下4个角色:

1、Product 产品类,一般是多个部件组成的复杂对象,由具体建造者来创建其各个零部件。

通用代码如下:

public class Product {

    /**
     * 定义一些复杂的属性
     */

    public void doSomething() {
        //处理业务逻辑
    }
}

2、Builder 抽象建造者,包含创建产品各个子部件的抽象方法以及返回复杂产品的方法。

通用代码如下:

public abstract class Builder {

    /**
     * 设置不同的模块组装产品
     */
    public abstract void setPart();

    /**
     * 构建产品
     *
     * @return
     */
    public abstract Product buildProduct();
}

3、ConcreteBuilder 具体建造者,实现抽象 Builder 定义的所有方法,并且返回一个装配好的对象。

通用代码如下:

public class ConcreteBuilder extends Builder {

    private Product product = new Product();

    @Override
    public void setPart() {
        //完成组装逻辑:方法的执行顺序、不同方法的组合等
    }

    @Override
    public Product buildProduct() {
        //返回装配好的实体类
        return product;
    }
}

4、Director 指挥者,负责安排已有模块的顺序,然后调用 Builder 建造产品。

通用代码如下:

public class Director {

    /**
     * 不同的产品由不同的方法实现
     *
     * @return
     */
    public Product getProduct() {
        Builder builder = new ConcreteBuilder();
        builder.setPart();
        return builder.buildProduct();
    }
}

优点

        1、封装性,在建造者模式中,调用方不必知道产品内部组成的细节,将一个复杂对象的构建与它的表示分离,使得相同的创建过程可以创建不同的产品对象。

        2、扩展性,每个具体建造者都相互独立,替换具体建造者或新增具体建造者都很便捷。

        3、更关注"由零件一步一步地组装出产品对象" 。将复杂产品的创建步骤拆分到不同的方法中,使得创建过程更加清晰。

缺点

        1、建造者模式所创建的产品对象一般组成部分相似,如果产品的内部变化复杂,需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

        2、如果产品内部结构发生变化,建造者也要相应修改,有较大的维护成本。

模式扩展

        1、建造者模式的简化,如果系统中只需要一个具体建造者的话,可以省略抽象建造者。此时指挥者角色也省略,让Builder类同时扮演指挥者与建造者。

        2、在使用建造者模式的时候可以考虑一下模板方法模式,多了解设计模式的原理和优点,别孤立地思考一个模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值