建造者模式

      建造者模式,光从名称来看,是否觉得和工厂模式是否觉得有点相近呢?工厂是要生产东西,建造者也是要生产东西,看上去真心的没啥太大区别。其实从个人感觉来说,建造者模式感觉比工厂模式更加灵活,对于属性较多的产品,使用建造者模式可能要好些。(欢迎来批)

      《Java设计模式》中使用的例子是接着模版的方法来的,还是使用汽车的例子,汽车的动作有:启动(start),停止(stop),发动机轰鸣(engineBoom),喇叭叫(alarm)。运行(run),运行则是根据一定的顺序来排列之前提到的四个函数。根据需求分析,有多个品种的车子,每个品种的车的动作的顺序都不一样,现在的目标就是要合理地安排程序,来能够尽可能灵活地实现,多品种车子的创建。

      首先,先定义车的模型(抽象模型),其中,sequence是表示动作执行的顺序,最重要的是run函数将要根据sequence来实现方法的执行,这样增大了灵活性,对于每个车子,只要通过函数设定好好sequence即可。

package com.cbf4life;

import java.util.ArrayList;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 定义一个车辆模型的抽象类,所有的车辆模型都继承这里类
 */
public abstract class CarModel {
    // 这个参数是各个基本方法执行的顺序
    private ArrayList<String> sequence = new ArrayList<String>();

    /*
     * 模型是启动开始跑了
     */
    protected abstract void start();

    // 能发动,那还要能停下来,那才是真本事
    protected abstract void stop();

    // 喇叭会出声音,是滴滴叫,还是哔哔叫
    protected abstract void alarm();

    // 引擎会轰隆隆的响,不响那是假的
    protected abstract void engineBoom();

    // 那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑
    final public void run() {
        // 循环一遍,谁在前,就先执行谁
        for (int i = 0; i < this.sequence.size(); i++) {
            String actionName = this.sequence.get(i);
            if (actionName.equalsIgnoreCase("start")) { // 如果是start关键字,
                this.start(); // 开启汽车
            } else if (actionName.equalsIgnoreCase("stop")) { // 如果是stop关键字
                this.stop(); // 停止汽车
            } else if (actionName.equalsIgnoreCase("alarm")) { // 如果是alarm关键字
                this.alarm(); // 喇叭开始叫了
            } else if (actionName.equalsIgnoreCase("engine boom")) { // 如果是engine
                                                                        // boom关键字
                this.engineBoom(); // 引擎开始轰鸣

            }
        }
    }

    // 把传递过来的值传递到类内
    final public void setSequence(ArrayList<String> sequence) {
        this.sequence = sequence;
    }
}
View Code

      然后是奔驰和宝马的模型,各做各的事:

package com.cbf4life;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 奔驰车模型
 */
public class BenzModel extends CarModel {
    @Override
    protected void alarm() {
        System.out.println("奔驰车的喇叭声音是这个样子的...");
    }

    @Override
    protected void engineBoom() {
        System.out.println("奔驰车的引擎是这个声音的...");
    }

    @Override
    protected void start() {
        System.out.println("奔驰车跑起来是这个样子的...");
    }

    @Override
    protected void stop() {
        System.out.println("奔驰车应该这样停车...");
    }
}
View Code
package com.cbf4life;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 宝马车模型
 */
public class BMWModel extends CarModel {
    @Override
    protected void alarm() {
        System.out.println("宝马车的喇叭声音是这个样子的...");
    }

    @Override
    protected void engineBoom() {
        System.out.println("宝马车的引擎是这个声音的...");
    }

    @Override
    protected void start() {
        System.out.println("宝马车跑起来是这个样子的...");
    }

    @Override
    protected void stop() {
        System.out.println("宝马车应该这样停车...");
    }
}
View Code

      然后是建造者:carbuilder,它的工作就是根据需求生产汽车:

package com.cbf4life;

import java.util.ArrayList;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 要什么顺序的车,你说,我给建造出来
 */
public abstract class CarBuilder {
    // 建造一个模型,你要给我一个顺序要,就是组装顺序
    public abstract void setSequence(ArrayList<String> sequence);

    // 设置完毕顺序后,就可以直接拿到这个车辆模型
    public abstract CarModel getCarModel();
}
View Code

      接下来是,奔驰和宝马的builder:

package com.cbf4life;

import java.util.ArrayList;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 各种设施都给了,我们按照一定的顺序制造一个奔驰车
 */
public class BenzBuilder extends CarBuilder {
    private BenzModel benz = new BenzModel();

    @Override
    public CarModel getCarModel() {
        return this.benz;
    }

    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.benz.setSequence(sequence);
    }
}
View Code
package com.cbf4life;

import java.util.ArrayList;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 第 88 页 您的设计模式 给定一个顺序,返回一个宝马车
 */
public class BMWBuilder extends CarBuilder {
    private BMWModel bmw = new BMWModel();

    @Override
    public CarModel getCarModel() {
        return this.bmw;
    }

    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.bmw.setSequence(sequence);
    }
}
View Code

      builder只根据需求创造出一个汽车,提供了接收参数(sequence)和返回的生产实例的接口。虽然builder的功能类似工厂,但是他只是完成创造汽车的工作,如果一定要和工厂模式来比较的话,它的工作是工厂的一部分。最后一个类是Director类,Director整体才算是一个建造者:

package com.cbf4life;

import java.util.ArrayList;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 导演安排顺序,生产车辆模型
 */
public class Director {
    private ArrayList<String> sequence = new ArrayList();
    private BenzBuilder benzBuilder = new BenzBuilder();

    private BMWBuilder bmwBuilder = new BMWBuilder();

    /*
     * A类型的奔驰车模型,先start,然后stop,其他什么引擎了,喇叭一概没有
     */
    public BenzModel getABenzModel() {
        // 清理场景,这里是一些初级程序员不注意的地方
        this.sequence.clear();
        // 这只ABenzModel的执行顺序
        this.sequence.add("start");
        this.sequence.add("stop");
        // 按照顺序返回一个奔驰车
        this.benzBuilder.setSequence(this.sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }

    /*
     * B型号的奔驰车模型,是先发动引擎,然后启动,然后停止,没有喇叭
     */
    public BenzModel getBBenzModel() {
        this.sequence.clear();
        this.sequence.add("engine boom");
        this.sequence.add("start");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(this.sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }

    /*
     * C型号的宝马车是先按下喇叭(炫耀嘛),然后启动,然后停止
     */
    public BMWModel getCBMWModel() {
        this.sequence.clear();
        this.sequence.add("alarm");
        this.sequence.add("start");
        this.sequence.add("stop");
        this.bmwBuilder.setSequence(this.sequence);

        return (BMWModel) this.bmwBuilder.getCarModel();
    }

    /*
     * D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止,牛叉
     */
    public BMWModel getDBMWModel() {
        this.sequence.clear();
        this.sequence.add("start");
        this.bmwBuilder.setSequence(this.sequence);
        return (BMWModel) this.benzBuilder.getCarModel();
    }
    /*
     * 这里还可以有很多方法,你可以先停止,然后再启动,或者一直停着不动,静态的嘛 导演类嘛,按照什么顺序是导演说了算
     */
}
View Code

      注意,Director中定义了所有可能的出现的情况,然后调用相应的Builder来实现。最后是测试程序:

package com.cbf4life;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 第 94 页 您的设计模式 这里是牛叉公司的天下,他要啥我们给啥
 */
public class Client {
    public static void main(String[] args) {
        Director director = new Director();
        // 1W辆A类型的奔驰车
        for (int i = 0; i < 10; i++) {
            director.getABenzModel().run();
        }
        // 100W辆B类型的奔驰车
        for (int i = 0; i < 10; i++) {
            director.getBBenzModel().run();
        }
        // 1000W量C类型的宝马车
        for (int i = 0; i < 10; i++) {
            director.getCBMWModel().run();
        }
    }
}
View Code

       整体感觉来看,制造者模式与工厂模式非常类似。对于这个例子,如果用工厂模式来思考的话:需要定义两个工厂BMWFactory和BenzFactory,这两个工厂分别生产宝马和奔驰,每个工厂中会有各种型号的车辆的生产方法。嗯嗯,应该是这样,不服来辩^_^

posted @ 2014-04-19 17:15  joy06  阅读(142)  评论(0编辑  收藏  举报