设计模式原则11----建造者模式

个人博客:打开链接

建造者模式定义

建造者模式(Builder Pattern) 也叫做生成器模式,其定义如下:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

车模例子

例子:我们要生产一个简单车模(汽车模型),汽车模型要有启动、停止、引擎发出声音、喇叭响等功能。现在我要让用户根据自己的喜好来选择这些功能的顺序。
我们做出了下面的设计,其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();
    }

}

我们现在的设计能够满足客户的要求。可是如果有多个用户呢?可能你需要设计多个场景类来满足。难道你要一个一个的写场景类么?这会把你逼疯的… 我们为了每种模型产品模型定义一个创造者,你要啥顺序直接告诉创造者,由创造者来创建,于是乎我们就有了如下UML类图:
这里写图片描述
增加了一个CarBuilder抽象类,由它来组装各个车模,要什么类型什么顺序的车辆模型,都由相关的子类完成。

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

    private BMWModel bmw;

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

    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.bmw.setSequence(sequence);
    }
}
//场景类
public class Client {
    public static void main(String[] args) {
        /*
         *
         */
        //存放run的顺序
        ArrayList<String> sequence = new ArrayList<String>();
        sequence.add("engine boom");//客户要求,run的时候先发动引擎
        sequence.add("start");//启动起来
        sequence.add("stop");//开了一段时间就停下来
        //要一个奔驰车
        BenzBuilder benzBuilder = new BenzBuilder();
        //把顺序给这个builder类,制造出这样一个车出来
        benzBuilder.setSequence(sequence);
        //制造出一个奔驰车
        BenzModel = benz = (BenzModel) benzBuilder.getCarModel();
        //奔驰车跑一下看看
        benz.run();
    }
}

为了实现车模的四个过程执行顺序可任意,我们在引入一个Direct导演类,负责按照指定的顺序生成模型,其UML类如为:
这里写图片描述

//导演类
public class Director {
    private ArrayList<String> sequence = new ArrayList<String>();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BMWBuilder bmwBuilder = new BMWBuilder();
    /*
     * A类型的奔驰车
     */
    public BenzModel getABenzModel(){
        this.sequence.clear();
        this.sequence.add("start");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(sequence);
        return (BenzModel)this.benzBuilder.getCarModel();
    }
    /*
     * B类型的奔驰车
     */
    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();
        }
    }

}

建造者模式的通用类图

这里写图片描述
Product产品类
通常是实现了模板方法模式,也就是有模板方法和基本方法。
Builder抽象建造者
规范产品的组建,一般是由子类实现。
ConcreteBuilder具体创建者
实现抽象类定义的所有方法,并且返回一个组建好的对象。
Director导演类
负责安排已有模块的顺序,然后告诉Builder开始创建。

//产品类
public class Product {
    public void doSomething() {
        //独立业务处理
    }
}

//抽象创造者
public abstract class Builder {
    //设置产品的不同部分,以获得不同的产品
    public abstract void setPart();
    //创建产品
    public abstract Product buildProduct();
}

//具体创造者
public class  ConcreteProduct extends Builder {
    private Product product = new Product();
    //设置产品零件
    public void setPart() {
        /*
         *产品类内部的逻辑处理
         */
    }
    //组建一个产品
    public Product buildProduct() {
        return product;
    }
}

//导演类
public class Director {
    private Builder builder = new ConcreteProduct();
    //构建不同的产品
    public Product getAProduct() {
        builder.setPart();
        /*
         *设置不同的零件,产生不同的产品
         */
        return builder.builderProduct();
    }
}

建造者模式的优点

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

建造者模式的使用场景

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

建造者模式的注意事项

建造者模式关注的是零件类型和装配工艺(顺序),而工厂方法关心的整体的对象。二者虽然都是创建类设计模式,但还是有很大不同,不要用混了。
建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同;而工厂方法模式则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤奋的凯尔森同学

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值