设计模式系列-模板方法- Template Method

案例

经常做饭的同学都比较熟悉炒菜的流程,主流程是热锅、热油、加配料、放菜翻炒、装碟,每道菜的制作流程基本一致,但是每个步骤对每道菜来讲是不同的,现在要抄两道菜,一是酸辣土豆丝,制作流程:热锅、加豆油、加辣椒和醋、放入土豆丝翻炒、装碟;二是西红柿炒蛋:热锅、加菜籽油、加鸡蛋、放入西红柿翻炒、装碟。
以上描述了案例基本需求,下面先介绍模板方法模式的定义,然后用此模式实现案例需求。

模板方法模式

在一个方法里定义一套算法的骨架并把算法的细节部分委托给子类实现,也就是说,子类实现算法的细节步骤而不会改变算法的整体骨架。
此模式的抽象实现

  • 首先定义一个抽象类,包含一个final 方法定义算法的骨架,抽象类还包含了算法骨架的细节步骤方法,包含抽象方法和非抽象方法。
  • 定义具体实现类,继承抽象类,实现抽象类的抽象方法,也可以覆盖非抽象方法。

拿我们上面的案例来说明,首先定义抽象类 ChaoCai ,炒菜的主流程封装的在抽象类的 final 方法里,再定义两个实现类 ChaoTuTouXiHongShiChaoDan

案例模板方法的实现

public abstract class ChaoCai {

    public final void chao() {
        reGuo();
        jiaYou();
        jiaCaiLiao();
        fangCaiFanChao();
        zhuangDie();
    }

    //装碟
    protected abstract void zhuangDie();

    //放菜翻炒
    protected abstract void fangCaiFanChao();

    //加材料
    protected abstract void jiaCaiLiao();

    //加油
    protected abstract void jiaYou();

    //热锅
    protected void reGuo() {
        System.out.println("开火热锅...");
    }
}

//酸辣土豆丝
public class ChaoTuDou extends ChaoCai {

    @Override
    protected void zhuangDie() {
        System.out.println("装大碟");
    }

    @Override
    protected void fangCaiFanChao() {
        System.out.println("放土豆丝");
    }

    @Override
    protected void jiaCaiLiao() {
        System.out.println("放辣椒和醋");
    }

    @Override
    protected void jiaYou() {
        System.out.println("加豆油");
    }
}

public class XiHongShiChaoDan extends ChaoCai {

    @Override
    protected void zhuangDie() {
        System.out.println("装小盘子");
    }

    @Override
    protected void fangCaiFanChao() {
        System.out.println("加西红柿");
    }

    @Override
    protected void jiaCaiLiao() {
        System.out.println("加入鸡蛋");
    }

    @Override
    protected void jiaYou() {
        System.out.println("加菜子油");
    }
}

public class ChaoCaiTest {

    public static void main(String[] args) {
        ChaoCai chaoCai = new ChaoTuDou();
        chaoCai.chao();
        chaoCai = new XiHongShiChaoDan();
        chaoCai.chao();
    }
}

输出结果:
开火热锅…
加豆油
放辣椒和醋
放土豆丝
装大碟
开火热锅…
加菜子油
加入鸡蛋
加西红柿
装小盘子

Java 类库模板方法模式的应用

在 java.util.AbstractList 中的 addAll 方法使用了模板方法,代码如下:

public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        boolean modified = false;
        for (E e : c) {
            add(index++, e);
            modified = true;
        }
        return modified;
}

其中 add 方法定义如下,目的是让子类覆盖实现

public void add(int index, E element) {
        throw new UnsupportedOperationException();
}

总结

模板方法模式提升代码复用并解耦代码实现,但缺点是利用继承,违反了组合优于继承 原则,此模式在框架(Spring 、Mybatis) 出现的频率很高,框架利用此模式定义一套业务的骨架,让子类是定制化具体的业务行为,父类利用final 修饰来防止子类更改算法的或业务的骨架。

源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值