设计模式学习 - 建造者模式(Builder)

建造者模式简介

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。用户只需指定需要建造的类型就可以得到它们,而具体的建造的过程和细节无需知道。

UML结构图

这里写图片描述

  • Builder:抽象建造类(或接口),抽象方法含有两部分,一部分是各个组件设置赋值的方法,另外一个是带返回值(具体产品类Product)的方法。
  • ConcreteBuilder:具体建造类,继承于Builder类,实现了抽象类定义的所有方法,同时返回一个已创建好的Product具体对象。
  • Product:具体产品类,定义各个组件的属性(实体类)。
  • Director:导演类,负责安排各个组件创建顺序。

建造者模式的实现

使用步骤

  1. 定义具体产品类Product。
  2. 定义抽象建造Builder类,也可以用接口来定义,其中含有Product类属性赋值方法,另外需定义一个带Product类的返回值方法。
  3. 定义具体建造类,继承于抽象建造类,实现类抽象类中的所有方法,并返回一个创建好的Product对象,需要依赖于Product类,一般Product类的实例化是在成员变量初始化,或者在构造函数中初始化。
  4. 定义导演类,导演类没有过多的要求,只负责各个组件的创建顺序,最后返回一个具体Product对象。
  5. 使用者调用,先实现具体建造类,再把该对象传入导演类中。

以上就是建造者模式常规步骤。

例子

下面以造汽车为例子,汽车一般分为四大组成部分,分别是发动机、底盘、车身、电子设备。

1、定义具体产品Cart类,成员变量分为发动机、底盘、车身、电子设备。

/**
 * 
 * @author 13480
 * 具体产品类,定义各个零部件属性变量
 */
public class Cart {
    //发动机
    private String mEngine;
    //底盘
    private String mChassis;
    //车身
    private String mCarBody;
    //电子设备
    private String mERP;

    public void setmEngine(String mEngine) {
        this.mEngine = mEngine;
    }
    public void setmChassis(String mChassis) {
        this.mChassis = mChassis;
    }
    public void setmCarBody(String mCarBody) {
        this.mCarBody = mCarBody;
    }
    public void setmERP(String mERP) {
        this.mERP = mERP;
    }

}

2、创建抽象建造Builder类,定义发动机、底盘、车身、电子设备部件创建方法,以及各个部件组装成的成品create方法。

/**
 * 
 * @author 13480
 * 抽象建造者类(也可用接口定义):主要分为两部分方法构成
 * 一部分:就是各个零部件的创建 的方法
 * 另外一部分:把各个零部件组成成成品 的方法
 */
public abstract class Builder {
    //创建发动机
    public abstract void buildEngine(String engine);

    //创建底盘
    public abstract void buildChassis(String chassis);
    //创建车身
    public abstract void buildCarBody(String carBody);
    //创建电子设备
    public abstract void buildERP(String erp);

    //集成各个组件组装成汽车
    public abstract Cart create();

}

3、定义具体建造类,继承于Builder类,比如现在造一辆比亚迪汽车和长安汽车。

---------------------------比亚迪----------------
public class BYDCartBuilder extends Builder{

    private Cart mCar=new Cart();

    @Override
    public void buildEngine(String engine) {
        mCar.setmEngine(engine);
    }

    @Override
    public void buildChassis(String chassis) {
        mCar.setmChassis(chassis);
    }

    @Override
    public void buildCarBody(String carBody) {
        mCar.setmCarBody(carBody);
    }
    @Override
    public void buildERP(String erp) {
        mCar.setmERP(erp);
    }
    @Override
    public Cart create() {
        return mCar;
    }

}

-------------------------------长安汽车--------------
public class ChangAnCarBuilder extends Builder{

    private Cart mCar=new Cart();
    @Override
    public void buildEngine(String engine) {
        mCar.setmEngine(engine);
    }

    @Override
    public void buildChassis(String chassis) {
        mCar.setmChassis(chassis);
    }

    @Override
    public void buildCarBody(String carBody) {
        mCar.setmCarBody(carBody);
    }

    @Override
    public void buildERP(String erp) {
        mCar.setmERP(erp);
    }
    @Override
    public Cart create() {
        return mCar;
    }

}

4、定义导演类统一组装过程

/**
 * 
 * @author 13480
 * 统一组装类(指挥类):可以简单理解是一个工具类,用来操作具体产品类
 * 主要的作用是规范流程,比如先组装底盘,还是发动机等等
 */
public class Director {

    private Builder mBuilder;

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

    /**
     * 规范制造流程
     */
    public Cart createCar(String chassis,String engine,String erp,String carBody){
        mBuilder.buildChassis(chassis);
        mBuilder.buildEngine(engine);
        mBuilder.buildERP(erp);
        mBuilder.buildCarBody(carBody);
        return mBuilder.create();
    }
}

5、使用者调用

public class Test {

    public static void main(String[] args) {

        //组装比亚迪汽车
        BYDCartBuilder bydCarBuilder = new BYDCartBuilder();
        //组装长安汽车
        ChangAnCarBuilder changAnCarBuilder = new ChangAnCarBuilder();

        Director director1 = new Director(bydCarBuilder);
        Director director2 = new Director(changAnCarBuilder);
        Cart createCar = director1.createCar("比亚迪底盘", "发动机", "电子设备", "车身");
        Cart createCar2 = director2.createCar("长安底盘", "发动机", "电子设备", "车身");

    }

}

使用场景及优缺点

优点

  • 可以把复杂实现逻辑封装起来,使用者无需知道内部实现细节。
  • 由于每个具体建造者类是相互独立的,没有任何关联,因此可以针对不同建造类实现不同功能,体现了扩展的特性。

缺点

  • 会产生很多Builder类和导演类。

使用场景

其实根据优点就大概知道使用场景,一般是用于某些参数设置比较多的场景或者内部逻辑比较复杂,比如说封装图片加载框架,图片加载需设置的参数比较多,占位图、预加载图、错误图、缓存策略、加载样式……

改进

针对建造者模式的缺点,可以稍微改进点,可以把具体建造者类和导演类进行合并,减少了导演类的定义,如下:

public class BYDCart {

    private BYDCartBuilder mBuilder;

    public BYDCart() {
        mBuilder=new BYDCartBuilder();
    }

    public Cart createCart(String chassis,String engine,String erp,String carBody){
        mBuilder.buildChassis(chassis);
        mBuilder.buildEngine(engine);
        mBuilder.buildERP(erp);
        mBuilder.buildCarBody(carBody);
        return mBuilder.create();
    }

     class BYDCartBuilder extends Builder{

        private Cart mCar=new Cart();


        @Override
        public void buildEngine(String engine) {
            mCar.setmEngine(engine);
        }


        @Override
        public void buildChassis(String chassis) {
            mCar.setmChassis(chassis);
        }


        @Override
        public void buildCarBody(String carBody) {
            mCar.setmCarBody(carBody);
        }


        @Override
        public void buildERP(String erp) {
            mCar.setmERP(erp);
        }

        @Override
        public Cart create() {
            return mCar;
        }

    }

}

猜你喜欢

转载自blog.csdn.net/hzw2017/article/details/80767623