24设计模式-模板方法模式(9)

本文通过一个简单的汽车模型实例,详细介绍了模板方法模式的概念及其应用。通过定义一个模板方法并在其中调用基本方法,实现了不同子类的具体行为差异,同时保持了一致的操作流程。

   首先做一个车模型。不考虑扩展性,那好办,我先设计个类图:


非常简单的实现,你要悍马模型,我就给你悍马模型,先写个抽象类,然后两个不同型号的模型实现类,那我们把这个程序实现出来:HummerModel 抽象类的程序清单如下

package com.cbf4life;
/**
*Hummer Model是悍马车辆模型的意思,不是悍马美女车模
*/
public abstract class HummerModel {
/*
*首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正
*是要能够发动起来,那这个实现要在实现类里了
*/
    public abstract void start();
    //能发动,那还要能停下来,那才是真本事
    public abstract void stop();
    //喇叭会出声音,是滴滴叫,还是哔哔叫
    public abstract void alarm();
    //引擎会轰隆隆的响,不响那是假的
    public abstract void engineBoom();
    //那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑
    public void run() {
        //先发动汽车
        this.start();
        //引擎开始轰鸣
        this.engineBoom();
        //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭
        this.alarm();
        //到达目的地就停车
        this.stop();
    }
}

下面是 HummerH1Model.java 程序清单:

package com.cbf4life;
/**
*悍马车是每个越野者的最爱,其中H1最接近军用系列
*/
public class HummerH1Model extends HummerModel {

    @Override
    public void alarm() {
        System.out.println("悍马H1鸣笛...");
    }

    @Override
    public void engineBoom() {
        System.out.println("悍马H1引擎声音是这样在...");
    }

    @Override
    public void start() {
        System.out.println("悍马H1发动...");
    }

    @Override
    public void stop() {
        System.out.println("悍马H1停车...");
    }
}

下面是 HummerH2Model.java 的程序清单:

package com.cbf4life;
/**
*H1和H2有什么差别,还真不知道,真没接触过悍马
*/
public class HummerH2Model extends HummerModel {

    @Override
    public void alarm() {
        System.out.println("悍马H2鸣笛...");
    }

    @Override
    public void engineBoom() {
        System.out.println("悍马H2引擎声音是这样在...");
    }

    @Override
    public void start() {
        System.out.println("悍马H2发动...");
    }

    @Override
    public void stop() {
        System.out.println("悍马H2停车...");
    }
}

类图修改完毕了,程序也该好了,提交给老大,老大一看,挺好,就开始生产了,并提交给客户使用了,那客户是如何使用的呢?类图上增加一个 Client 类,就是客户,我们这个是用 main 函数来代替他使用,类图如下:

然后看增加的 Client.java 程序,非常的简单:

package com.cbf4life;
/**
*客户开始使用这个模型
*/
public class Client {
    public static void main(String[] args) {
        //客户开着H1型号,出去遛弯了
        HummerModel h1 = new HummerH1Model();
        h1.run(); //汽车跑起来了;

        //客户开H2型号,出去玩耍了
        HummerModel h2 = new HummerH2Model();
        h2.run();
    }
}

运行的结果如下:

悍马H1发动...

悍马H1引擎声音是这样在...

悍马H1鸣笛...

悍马H1停车...

悍马H2发动...

悍马H2引擎声音是这样在...

悍马H2鸣笛...

悍马H2停车...

非常非常的简单,那如果我告诉这就是模板方法模式你会不会很不屑呢?就这模式,太简单了,我一直在使用呀,是的,你经常在使用,但你不知道这是模板方法模式,那些所谓的高手就可以很牛 X 的说“用模板方法模式就可以实现…”,你还要很崇拜的看着,哇,牛人,模板方法模式是什么呀?

那我们总结一下模板方法模式,模板方法模式就是在模板方法中按照一个的规则和顺序调用基本方法,具体到我们上面那个例子就是 run 方法按照规定的顺序(先调用 start,然后再调用 engineBoom,再调用alarm,最后调用 stop)调用本类的其他方法,并且由 isAlarm 方法的返回值确定 run 中的执行顺序变更,通用类图如下:





总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 二、设计模式的六大原则 1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科 3、依赖倒转原则(Dependence Inversion Principle) 这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle) 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。 5、迪米特法则(最少知道原则)(Demeter Principle) 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle) 原则是尽量使用合成/聚合的方式,而不是使用继承。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值