设计模式(十六):建造者模式

一、概述  

  建造者模式很容易让人想到建房子,不管建刚需房、改善房还是别墅,它们都离不开地基、柱子、层面和墙体这些组成部分,建筑工人就是把这些组成部分一个个建起来,最后连成一体建出一栋栋楼房。

来看看建造者模式的定义,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建房子的过程都是相似的,但可以建出形形色色的房子。

二、结构类图

三、应用实例

  我们用制造自行车为例子讲解建造者模式,自行车由车架、轮胎、脚踏等部件组成,如下图所示。自行车制造公司就是把这些零部件组装起来。

自行车制造公司的工程部门相当于指挥者,生产部门相当于建造者,当今共享单车做的比较大的摩拜和ofo相当于客户,单车就是产品了。结构图如下所示:

  一起来看看如何用代码来实现

  1、定义创建者接口,也就是生产线接口

package com.jet.pattern.builder;

import com.jet.pattern.builder.impl.Bike;

/**
 * description:
 * 自行车生产线接口
 * Created by chenzanjin on 2017/2/22.
 */
public interface BikeBuilder {
    // 组装轮胎
    public void buildTyres();
    // 组装车架
    public void buildFrame();
    // 组装GPS定位装置
    public void buildGPS();
    // 获取自行车
    public Bike getBike();
}

  2、定义摩拜单车生产线

package com.jet.pattern.builder.impl;

import com.jet.pattern.builder.BikeBuilder;

/**
 * description:
 * 摩拜单车生产线
 * Created by chenzanjin on 2017/2/22.
 */
public class MoBikeBuilder implements BikeBuilder {
    // 拥有单车对象
    Bike bike = new Bike();
    @Override
    public void buildTyres() {
        bike.setTyre("橙色轮胎");
    }

    @Override
    public void buildFrame() {
        bike.setFrame("橙色车架");
    }

    @Override
    public void buildGPS() {
        bike.setGps("mobike定制版GPS定位装置");
    }

    @Override
    public Bike getBike() {
        return bike;
    }
}

  3、定义ofo单车生产线

package com.jet.pattern.builder.impl;

import com.jet.pattern.builder.BikeBuilder;

/**
 * description:
 * ofo单车生产线
 * Created by chenzanjin on 2017/2/22.
 */
public class OfoBikeBuilder implements BikeBuilder {
    // 拥有单车对象
    Bike bike = new Bike();
    @Override
    public void buildTyres() {
        bike.setTyre("黑色轮胎");
    }

    @Override
    public void buildFrame() {
        bike.setFrame("黄色车架");
    }

    @Override
    public void buildGPS() {
        bike.setGps("ofo定制版GPS定位装置");
    }

    @Override
    public Bike getBike() {
        return bike;
    }
}

   4、定义单车对象

package com.jet.pattern.builder.impl;

/**
 * description:
 * 自行车对象
 * Created by chenzanjin on 2017/2/22.
 */
public class Bike {
    // 轮胎
    private String tyre;
    // 车架
    private String frame;
    // GPS定位装置
    private String gps;

    public String getTyre() {
        return tyre;
    }

    public void setTyre(String tyre) {
        this.tyre = tyre;
    }

    public String getFrame() {
        return frame;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public String getGps() {
        return gps;
    }

    public void setGps(String gps) {
        this.gps = gps;
    }
}

  5、定义工程部

package com.jet.pattern.builder.impl;

import com.jet.pattern.builder.BikeBuilder;

/**
 * description:
 * 工程部门作为指挥者,可以指导生产部门作业
 * Created by Administrator on 2017/2/22.
 */
public class EngineeringDepartment {
    // 用户告知指挥者想要什么样的单车
    BikeBuilder bikeBuilder;
    public EngineeringDepartment(BikeBuilder bikeBuilder){
        this.bikeBuilder = bikeBuilder;
    }

    // 指导组装单车
    public void Construct(){
        bikeBuilder.buildTyres();
        bikeBuilder.buildFrame();
        bikeBuilder.buildGPS();
    }
}

  6、测试类

package com.jet.pattern.builder.impl;

import com.jet.pattern.builder.BikeBuilder;

/**
 * description:
 * 建造者测试类
 * Created by Administrator on 2017/2/22.
 */
public class Test {
    public static void main(String[] args) {
        // 建造摩拜单车
        BikeBuilder moBikeBuilder = new MoBikeBuilder();
        EngineeringDepartment ed1 = new EngineeringDepartment(moBikeBuilder);
        ed1.Construct();// 指导组装
        // 产出单车,体现建造和显示分离
        Bike moBike = moBikeBuilder.getBike();

        // 建造ofo单车
        BikeBuilder ofoBikeBuilder = new MoBikeBuilder();
        EngineeringDepartment ed2 = new EngineeringDepartment(ofoBikeBuilder);
        ed2.Construct();// 指导组装
        Bike ofoBike = ofoBikeBuilder.getBike();

    }
}

四、优缺点

  1、优点

  (1)、产品的建造和表示分离,实现了解耦。

  (2)、隐藏了产品的建造细节,用户只需关心产品的表示,而不需要了解是如何创建产品的。

  (3)、体现了开闭原则,如上代码所示,如果需要再生产其他共享单车,只需要再开一条生产线即可,不影响其他生产线的作业。

  2、缺点

  (1)、当建造者过多时,会产生很多类,难以维护。

五、总结

  建造者模式的使用场合是当创建复杂对象时,把创建对象成员和装配方法分离出来,放在建造者类中去实现,用户使用该复杂对象时,不用理会它的创建和装配过程,只关心它的表示形式。其实完全理解这个模式还是要一番思考的,难以搞懂的是指挥者似乎没什么存在的必要,在代码里也没体现它的作用,我们也可以把指挥者的方法放在建造者里面,但为什么没有这样做呢?我想这可能是考虑到单一责任原则,建造者只负责创建对象的各个部分,至于各个部分创建的顺序、装配方法它就不管了。还有就是当顺序要改变时,建造者可以不用改动,改动指挥者就好了,指挥者只有一个,建造者有很多,要改建造者就麻烦了。

posted @ 2017-02-22 22:47 jenkinschan 阅读(...) 评论(...) 编辑 收藏