深入理解设计模式之建造者模式

深入理解设计模式之建造者模式老大突然拉住我,喜滋滋地告诉我:“公司很满意我们做的模型,又签订了一个合同,把奔驰、宝马的车辆模型都交给我们公司制作了,不过这次额外增加了一个新需求:汽车的启动、停止、喇叭声音、引擎声音都由客户自己控制,想什么顺序就什么顺序”那我们开始设计,来看一下类图:类图比较简单,在CarModel中我们定义了一个setSequence方法,车辆模型的这几个动作要如何排布,是在这个ArrayList中定义的。然后run()方法根据sequence定义的顺序完成指定的顺序动作。我们来看模型抽象类代码:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

老大突然拉住我,喜滋滋地告诉我:“公司很满意我们做的模型,又签订了一个合同,把奔驰、宝马的车辆模型都交给我们公司制作了,不过这次额外增加了一个新需求:汽车的启动、停止、喇叭声音、引擎声音都由客户自己控制,想什么顺序就什么顺序”

那我们开始设计,来看一下类图:

深入理解设计模式之建造者模式

类图比较简单,在CarModel中我们定义了一个setSequence方法,车辆模型的这几个动作 要如何排布,是在这个ArrayList中定义的。然后run()方法根据sequence定义的顺序完成指定 的顺序动作。我们来看模型抽象类代码:

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 public void run() {
        //循环一边,谁在前,就先执行谁
        for (String actionName : this.sequence) {
            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;
    }
}

Jetbrains全家桶1年46,售后保障稳定

奔驰模型代码:

public class BenzModel extends CarModel {
    
    protected void alarm() {
        System.out.println("奔驰车的喇叭声音是这个样子的...");
    }

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

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

    protected void stop() {
        System.out.println("奔驰车应该这样停车...");
    }
}

宝马模型代码: 

public class BWMModel extends CarModel {
    protected void alarm() {
        System.out.println("宝马车的喇叭声音是这个样子的...");
    }

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

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

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

Client场景类:

class Client{
    public static void main(String[] args) {
        BenzModel benzModel = new BenzModel();
        //存放run的顺序
        ArrayList<String> sequence = new ArrayList<>();
        sequence.add("engine boom");
        sequence.add("start");
        sequence.add("stop");
        //执行顺序赋予奔驰车
        benzModel.setSequence(sequence);
        benzModel.run();
    }
}

运行结果如下:

深入理解设计模式之建造者模式

我们只满足了一个需求,还有下一个需求呀,然后是第二个宝马模型,只要启动、停止,其他的什么都不要;第三个模型,先喇叭,然后启动,然 后停止;第四个……直到把你逼疯为止,那怎么办?我们就一个一个地来写场景类满足吗? 不可能了,那我们要想办法来解决这个问题,有了!我们为每种模型产品模型定义一个建造者,你要啥顺序直接告诉建造者,由建造者来建造。

深入理解设计模式之建造者模式 抽象汽车组装者:

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

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

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

宝马车组装者:

public class BWMBuilder extends CarBuilder {
    private BWMModel bmw = new BWMModel();

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

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

修改后的场景类:

class Client {
    public static void main(String[] args) {
        ArrayList<String> sequence = new ArrayList<String>();
        //客户要求,run时候时候先发动引擎
        sequence.add("engine boom");
        //启动起来
        sequence.add("start");
        //开了一段就停下来
        sequence.add("stop");
        BenzBuilder benzBuilder = new BenzBuilder();
        benzBuilder.setSequence(sequence);
        CarModel carModel = benzBuilder.getCarModel();
        carModel.run();

    }
}

我们在做项目时,经常会有一个共识:需求是无底洞,是无理性的,不可能你告诉它不增加需求就不增加,这4个过程(start、stop、alarm、engine boom)按照排列组合有很多种,公司可以随意组合,它要什么顺序的车模我就必须生成什么顺序的 车模,客户可是上帝!那我们不可能预知他们要什么顺序的模型呀,怎么办?封装一下,找 一个导演,指挥各个事件的先后顺序,然后为每种顺序指定一个代码,你说一种我们立刻就 给你生产处理,好方法,厉害!我们先修改一下类图

深入理解设计模式之建造者模式

public class Director {
    private ArrayList<String> sequence = new ArrayList();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BWMBuilder bmwBuilder = new BWMBuilder();

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

    public BWMModel getCBMWModel() {
        this.sequence.clear();
        this.sequence.add("alarm");
        this.sequence.add("start");
        this.sequence.add("stop");
        this.bmwBuilder.setSequence(this.sequence);
        return (BWMModel) this.bmwBuilder.getCarModel();
    } 
    
    /*
     * D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止
     */
    public BWMModel getDBMWModel() {
        this.sequence.clear();
        this.sequence.add("start");
        this.bmwBuilder.setSequence(this.sequence);
        return (BWMModel) this.benzBuilder.getCarModel();
    }
}

顺便说一下,大家看一下程序中有很多this调用。如果你要调用类中的成员变量或方法,需要在前面加上this关键字,不加也能正常地跑起来,但是不清晰,加上this关键字,我就是要调用本类中的成员变量或方法,而不是本方法中的一个变量。还有super方法也是一样,是调用父类的成员变量或者方法,那就加上这个关键字,不要省略.

建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:

Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分 离,使得同样的构建过程可以创建不同的表示。)深入理解设计模式之建造者模式

 建造者模式的优点

深入理解设计模式之建造者模式

 使用场景

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/226770.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号