YAZONG 我的开源

设计模式(十一)创建型模式(对象创建型模式)生成器/建造者-BUILDER

 
0 评论0 浏览

2、11建造者/生成器模式

定义

建造者模式也叫做生成器模式。

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

2)建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

通用类图

image.png

案例

public class Client1 {

    public static void main(String[] args) {

 

    }

}

/**

 * 产品类

 * 如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类.z

 */

class Product{

    public void doSomething(){

        //独立业务处理

    }

}

/**

 * 抽象建造者

 * 如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类.z

 */

abstract class Builder{

    //设置产品的不同部分,以获得不同的产品

    public abstract void setPart();

    //建造产品

    public abstract Product buildProduct();

}

 

/**

 * 具体建造者

 */

class ConcreteBuilder extends Builder{

 

    private Product product = new Product();

 

    //设置产品零件

    @Override

    public void setPart() {

        //产品类内的逻辑处理

    }

    //组件一个产品

    @Override

    public Product buildProduct() {

        return product;

    }

}

/**

 * 导演类

 */

class Director{

    private Builder builder = new ConcreteBuilder();

    //构建不同的产品

    public Product getProduct(){

        builder.setPart();

        //设置不同的零件,产生不同的产品

        return builder.buildProduct();

    }

}

场景案例(汽车)


public class Client2 {
    public static void main(String[] args) {
        Director director = new Director();
        for (int i = 0; i < 2; i++) {
            director.getBenzModel().run();
            System.out.println("-------------------");
        }
        System.out.println("====================");
        for (int i = 0; i < 2; i++) {
            director.getBMWModel().run();
            System.out.println("-------------------");
        }
    }
}

/**
 * 车辆模型的抽象类
 */
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 public void run(){
        //循环,在前面的先执行
        for(int i = 0;i < this.sequence.size();i++){
            String actionName = this.sequence.get(i);
            if("start".equalsIgnoreCase(actionName)){
                this.start();
            }else if("stop".equalsIgnoreCase(actionName)){
                this.stop();
            }else if("alarm".equalsIgnoreCase(actionName)){
                this.alarm();
            }else if("engineBoom".equalsIgnoreCase(actionName)){
                this.engineBoom();
            }
        }
    }
    //把传递过来的值传递到类中
    final public void setSequence(ArrayList<String> sequence){
        this.sequence = sequence;
    }

}

/**
 * 奔驰车模型
 */
class BenzModel extends CarModel{
    @Override
    protected void start() {
        System.out.println("奔驰..........start");
    }

    @Override
    protected void stop() {
        System.out.println("奔驰..........stop");
    }

    @Override
    protected void alarm() {
        System.out.println("奔驰..........alarm");
    }

    @Override
    protected void engineBoom() {
        System.out.println("奔驰..........engineBoom");
    }
}

/**
 * 宝马车模型
 */
class BMWModel extends CarModel{
    @Override
    protected void start() {
        System.out.println("宝马..........start");
    }

    @Override
    protected void stop() {
        System.out.println("宝马..........stop");
    }

    @Override
    protected void alarm() {
        System.out.println("宝马..........alarm");
    }

    @Override
    protected void engineBoom() {
        System.out.println("宝马..........engineBoom");
    }
}

/**
 * 抽象汽车组转者
 */
abstract class CarBuilder{
    //建造一个模型,安装给定的顺序来组装
    public abstract void setSequence(ArrayList<String> sequence);
    //设置完顺序后,可以直接拿到这个车辆模型
    public abstract CarModel getCarModel();
}

/**
 * 奔驰车组装者
 */
class BenzBuilder extends CarBuilder{

    private BenzModel model = new BenzModel();

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

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

/**
 * 宝马车组装者
 */
class BMWBuilder extends CarBuilder{

    private BMWModel model = new BMWModel();

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

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

/**
 * 导演类
 * 指挥各个事件的先后顺序
 */
class Director{

    private ArrayList<String> sequence = new ArrayList<>();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BMWBuilder bmwBuilder = new BMWBuilder();

    /**
     * 奔驰车某类模型
     * @return
     */
    public BenzModel getBenzModel(){
        //这里可能会引起数据混乱,只是作为案例使用,清理场景,这里一定要注意
        this.sequence.clear();
        //设置执行顺序
        this.sequence.add("start");
        this.sequence.add("stop");
        //按顺序返回一辆奔驰
        this.benzBuilder.setSequence(this.sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }

    /**
     * 宝马车某类模型
     * @return
     */
    public BMWModel getBMWModel(){
        //这里可能会引起数据混乱,只是作为案例使用,清理场景,这里一定要注意
        this.sequence.clear();
        //设置执行顺序
        this.sequence.add("engineBoom");
        this.sequence.add("alarm");
        this.sequence.add("start");
        this.sequence.add("stop");
        //按顺序返回一辆宝马
        this.bmwBuilder.setSequence(this.sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();
    }

}

奔驰..........start
奔驰..........stop
-------------------
奔驰..........start
奔驰..........stop
-------------------
====================
宝马..........engineBoom
宝马..........alarm
宝马..........start
宝马..........stop
-------------------
宝马..........engineBoom
宝马..........alarm
宝马..........start
宝马..........stop
-------------------

优点

1)封装性

使用建造者模式可以使客户端不必知道产品内部组成的细节。

2)建造者独立,容易扩展。

3)便于控制细节风险

由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

4)允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。

5)产品的实现可以被替换,因为客户只看到一个抽象的接口。

使用场景

1)相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。

2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用建造者模式。

3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。

4)在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反了设计的最初目标。

5)经常被用来创建组合结构。

注意事项

建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,虽然同为创建类模式,但是注重点不同。

建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同;而工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。


标题:设计模式(十一)创建型模式(对象创建型模式)生成器/建造者-BUILDER
作者:yazong
地址:https://blog.llyweb.com/articles/2020/07/01/1593613157760.html