建造者模式

作者: 大海孤了岛 | 来源:发表于2017-03-10 00:51 被阅读9次

实现一个汽车模型,可以由客户任意调整零件顺序


实现类图

car_model.png

1.先定义一个CarModel类,实现汽车的整体模型:
public abstract class CarModel {
    //记录零件步骤
    private ArrayList<String> sequence = new ArrayList<>();

    //设置步骤方法,并交给子类去实现
    protected abstract void start();

    protected abstract void stop();

    protected abstract void alarm();

    protected abstract void engineBoom();

    //运行汽车,设置为final类型,防止被子类修改
    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 sequence){
        this.sequence = sequence;
    }

}
2. 分别实现具体的汽车模型-宝马和奔驰
package original;

/**
 * Created by Administrator on 2017/3/9/009.
 * 实现奔驰车的零件
 */
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("奔驰车的引擎声音是这样的....");
    }
}


package original;

/**
 * Created by Administrator on 2017/3/9/009.
 * 实现宝马车的零件
 */
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("宝马车引擎声是这样的....");
    }
}
3. 客户可以根据自己的需求定义零件的顺序:
public class Client {
    public static void main(String[] args){
        //满足需求,可以由客户调整步骤
        BenzModel benz = new BenzModel();
        ArrayList<String> sequence = new ArrayList<>();
        sequence.add("engine boom");
        sequence.add("start");
        sequence.add("stop");
        benz.setSequence(sequence);
        benz.run();
    }
}
问题是我们这样做只满足和一个需求,如果出现更多的需求呢?因此,我们要设计一个中新的模式:为每种模型产品模型定义一个建造者,要什么顺序,由建造者来建造。

设计类图:

Paste_Image.png

1. 定义一个父类建造者
/**
 * Created by Administrator on 2017/3/9/009.
 * 定义一个汽车建造者父类
 */
public abstract class CarBuilder {
    //设置零件顺序
    public abstract void setSequence(ArrayList<String> sequence);
    //获取到汽车模型
    public abstract CarModel getCarModel();
}
2. 构建具体的奔驰建造者和宝马建造者
/**
 * Created by Administrator on 2017/3/9/009.
 * 实现具体的奔驰建造者
 */
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 this.benz;
    }
}

public class BMWBuilder extends CarBuilder {
    private BMWModel bmw = new BMWModel();
    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.bmw.setSequence(sequence);
    }

    @Override
    public CarModel getCarModel() {
        return this.bmw;
    }
}
3. 客户再次调用,只要将顺序交给建造者,就可以建造出相应的模型出来
public static void main(String[] args){
        //设置零件顺序
        ArrayList<String> sequence = new ArrayList<>();
        sequence.add("engine boom");
        sequence.add("start");
        sequence.add("stop");
        //创建建造者
        BenZBuilder builder = new BenZBuilder();
        //将零件顺序传递给建造者
        builder.setSequence(sequence);
        //根据零件顺序创建出既定的模型
        BenzModel benz = (BenzModel) builder.getCarModel();
        benz.run();
    }
4. 封装建造者,我们建立一个导演对象,指定各个事件的顺序,然后为每种顺序都指定一个代码,以便即可生产出对应的模型。

设计类图

Paste_Image.png

a. 建立导演对象:


public class Director {
    //定义顺序列表和建造者
    private ArrayList<String> sequence = new ArrayList<>();
    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(this.sequence);
        return (BenzModel) this.benZBuilder.getCarModel();
    }

    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();
    }

    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();
    }

    public BMWModel getDBMWModel(){
        this.sequence.clear();
        this.sequence.add("start");
        this.bmwBuilder.setSequence(this.sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();
    }
}

b. 这样我们就可以批量地生产各种不同种类型了,当需要增加类型时,只需在Director中添加即可生产。

  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();
        }

        for (int i = 0; i < 10; i ++){
            director.getCBMWModel().run();
        }
    }

建造者模式:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。


1. 通用类图:

Paste_Image.png

2. 角色:

a. Product类:
通常实现了模板方法模式,其中BenzModel和BMWModel就属于产品类。
b. Builder抽象建造者:
规范产品的组建,一般由子类实现,其中CarBuilder就是抽象建造者。
c. ConcreteBuilder具体建造者:
实现抽象类定义的所有方法,并且返回一个组建好的对象,其中BenzBuilder就属于具体建造者。
d. Director导演类:
负责安排已有的模板的顺序,然后告诉Builder开始建造。


3. 建造者模式的优点:

a. 封装性:
使用建造者模式可以使客户端不必知道产品内部组成的细节。
b. 建造者独立,易于扩展。
c. 便于控制细节风险:
由于具体的建造者是独立的,因此对于建造过程逐步细化,而不对其他的模块产生任何影响。


  1. 建造者的使用场景

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


相关文章

  • Builder Pattern in Java

    建造者模式:建造者模式定义建造者模式应用场景实现案例Jdk中的建造者模式建造者模式的优点建造者模式的缺点 建造者模...

  • 设计模式(4) 建造者模式

    什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与...

  • 建造者模式(部件构造)

    目录 建造者模式的理念 从 POJO 到建造者模式的思考 怎么来实现建造者模式 建造者模式在Android源码中的...

  • 【设计模式】之建造者Builder模式

    建造者模式 什么是建造者模式? 建造者模式属于创建型模式的一员,可以控制对象的实例化过程。建造者模式简化了复杂对象...

  • 建造者模式

    一、建造者模式介绍 二、建造者模式代码实例

  • 建造者模式

    建造者模式 首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和...

  • 建造者模式:深入理解建造者模式 ——组装复杂的实例

    目录: 一 建造者模式介绍 1.1 定义 1.2 为什么要用建造者模式(优点)? 1.3 哪些情况不要用建造者模式...

  • 设计模式之建造者模式

    设计模式之建造者模式 Intro 简介 建造者模式: 建造者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加...

  • 一、设计模式(构建模式)——03建造模式与原型模式

    建造者模式 建造型模式用于创建过程稳定,但配置多变的对象。 建造模式的实现要点: 在建造者模式中,指挥者是直接与客...

  • 创建型模式:建造者模式

    个人公众号原文:创建型模式:建造者模式 五大创建型模式之四:建造者模式。 简介 姓名 :建造者模式 英文名 :Bu...

网友评论

    本文标题:建造者模式

    本文链接:https://www.haomeiwen.com/subject/mitngttx.html