码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之禅——建造者模式

时间:2016-08-23 13:25:45      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:

建造者模式定义:
建造者模式也叫做生成器模式——将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

例子:我们要生产一个简单车模(汽车模型),汽车模型要有启动、停止、引擎发出声音、喇叭响等功能。现在我要让用户根据自己的喜好来选择这些功能的顺序~(接着上一篇模板方法模式的例子)

我们做出了下面的设计,见UML图
技术分享

见代码

//汽车模型的抽象类
public abstract class CarModel{
//sequence就是客户要求执行的方法的顺序
    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")){
                this.start();
            }else if(actionName.equalsIgnoreCase("stop")){
                this.stop();
            }else if(actionName.equalsIgnoreCase("alarm")){
                this.alarm();
            }else if(actionName.equalsIgnoreCase("engine boom")){
                this.engineBoom();
            }
        }
    }
    final public void setSequence(ArrayList<String> sequence){
        this.sequence = sequence;
    }
}
//Benz模型
public class BenzModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("奔驰车开始跑。。。");

    }

    @Override
    protected void stop() {
        System.out.println("奔驰车停下。。。");


    }

    @Override
    protected void alarm() {
        System.out.println("奔驰车喇叭响...");

    }

    @Override
    protected void engineBoom() {
        System.out.println("奔驰车的引擎发出声音了。。。");

    }
}
//宝马模型
public class BMWModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("宝马车开始跑。。。");

    }

    @Override
    protected void stop() {
        System.out.println("宝马车停下。。。");


    }

    @Override
    protected void alarm() {
        System.out.println("宝马车喇叭响...");

    }

    @Override
    protected void engineBoom() {
        System.out.println("宝马车的引擎发出声音了。。。");

    }

}
public class Client {


    public static void main(String[] args) {
        BenzModel benz = new BenzModel();
        ArrayList<String> sequence = new ArrayList<String>();
        sequence.add("engine boom");//客户要求,引擎先发出声音
        sequence.add("start");//开始跑
        sequence.add("stop");
        benz.setSequence(sequence);
        benz.run();
    }

}

ok,我们现在的设计能够满足客户的要求。可是如果有N个用户呢?可能你需要设计N个场景类来满足。当N=1000000000000时…….怎么办呢?

1、新加一个导演类!导演这里有所有的顺序,这样就可以避免根据客户临时提出来的需求来设计而手忙脚乱了。同时导演类起到封装的作用,避免高层模块深入到建造者内部的实现类。当建造者模式很大时,导演类可以有很多个。

2、然后再新加一个建造者类,建造者根据导演类的要求来生产具体的对象。

见UML图,(UML图有点小问题——导演类聚合多个汽车建造者,但不影响理解)
技术分享

见代码`

//产品类——汽车模型不变
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")){
                this.start();
            }else if(actionName.equalsIgnoreCase("stop")){
                this.stop();
            }else if(actionName.equalsIgnoreCase("alarm")){
                this.alarm();
            }else if(actionName.equalsIgnoreCase("engine boom")){
                this.engineBoom();
            }
        }
    }
    final public void setSequence(ArrayList<String> sequence){
        this.sequence = sequence;
    }
}
public class BMWModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("宝马车开始跑。。。");

    }

    @Override
    protected void stop() {
        System.out.println("宝马车停下。。。");


    }

    @Override
    protected void alarm() {
        System.out.println("宝马车喇叭响...");

    }

    @Override
    protected void engineBoom() {
        System.out.println("宝马车的引擎发出声音了。。。");

    }

}
public class BenzModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("奔驰车开始跑。。。");

    }

    @Override
    protected void stop() {
        System.out.println("奔驰车停下。。。");


    }

    @Override
    protected void alarm() {
        System.out.println("奔驰车喇叭响...");

    }

    @Override
    protected void engineBoom() {
        System.out.println("奔驰车的引擎发出声音了。。。");

    }
//我们新增的汽车建造者抽象类
public abstract class CarBuilder {
    public abstract void setSequence(ArrayList<String> sequence);
    public abstract CarModel getCarModel();
}
//宝马建造者实现类
public class BMWBuilder extends CarBuilder {

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

    @Override
    public CarModel getCarModel() {
        // TODO Auto-generated method stub
        return bmw;
    }

}
//奔驰建造者实现类
public class BenzBuilder extends CarBuilder {

    private BenzModel benz = new BenzModel();

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

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

}
//导演类
public class Director {
    private ArrayList<String> sequence = new ArrayList<String>();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BMWBuilder bmwBuilder = new BMWBuilder();

    public BenzModel getABenzModel(){
        this.sequence.clear();
        this.sequence.add("start");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(sequence);
        return (BenzModel)this.benzBuilder.getCarModel();
    }
    public BenzModel getBBenzModel(){
        this.sequence.clear();
        this.sequence.add("start");
        this.sequence.add("alarm");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(sequence);
        return (BenzModel)this.benzBuilder.getCarModel();
    }
    //好多种...

}
//场景类
public class Client {


    public static void main(String[] args) {
        Director director = new Director();
        for(int i = 0; i < 10; ++i){
            director.getABenzModel().run();
        }
        for(int i = 0; i < 10; ++i){
            director.getBBenzModel().run();
        }
    }

}

建造者模式也是有通用类图的,这个建议自己尝试一下~

建造者模式的优点

  • 封装性
  • 建造者独立,容易拓展。BenzBuilder和BMWBuilder是相互独立的,对系统的拓展非常有利。
  • 便于控制细节风险。因为具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生影响。

    建造者模式的使用场景

  • 相同的方法,不同的顺序,产生不同的事件结果时

  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时
  • 产品类非常复杂,或者产品类中的调用方法的顺序不同产生了不同的效能

建造者模式的注意事项

  • 建造者模式关注的是零件类型和装配工艺(顺序),而工厂方法关心的整体的对象。二者虽然都是创建类设计模式,但还是有很大不同,不要用混了~

设计模式之禅——建造者模式

标签:

原文地址:http://blog.csdn.net/tyronerenekton/article/details/52289842

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!