Java设计模式——模板方法(Template Method)以及策略模式比较

什么是模板方法

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。是基于继承的代码复用的基本模式。

结构类图
这里写图片描述


抽象模板【AbstractTemplate】

  • 【模板方法】templateMethod : 把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
  • 【抽象方法】abstractMethod : 父类中定义好规范只声明但不加以实现,由它的子类去实现。【一般以doXX()命名】
  • 【钩子方法】hookMethod : 由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。【view的onDraw()方法】
  • 【具体方法】concreteMethod : 一个具体方法由抽象类声明并实现,而子类并不实现。【父类私有方法】

举个栗子

根据上面的结构介绍,定义一个需求

东汉末年三国战乱,百姓流离失所,刘备为了统筹人心和坚固自己的事业,开始让张飞和关羽招兵买马,但是新兵报道需要以下几个环节

  • 自我介绍
  • 体能测试
  • 额外才艺秀【非必须】


父类方法。
abstract class AbstractShu {
    /**
     * templateMethod
     */
    public void rule(Soldier soldier) {
        System.out.println("【蜀】 介绍: " + doIntroduce(soldier));
        System.out.println("【蜀】 习武: " + show());
        if (!skill().equals("")) {
            System.out.println("【蜀】 额外技能: " + skill());
        }
    }
    /**
     * abstractMethod
     */
    abstract String doIntroduce(Soldier soldier);
    /**
     * hookMethod
     */
    protected String skill() {
        return "";
    }
    /**
     * concreteMethod
     */
    private String show() {
        return "10分钟体能测试";
    }
}

这个是刘备定义的用人和测试法则,所有招人的流程已经规定好了,自我介绍方法introduce由继承者们去实现,额外技能skill()可以拓展也可以不拓展。

继承者关

首先关羽捋了捋胡子

public class GuanAbsShu extends AbstractShu {
    @Override
    String doIntroduce(Soldier soldier) {
        return "小生姓" + soldier.getLastName() + ",名" + soldier.getName() + "," + soldier.getLocation() + "人也。夷门谱牒,梁苑冠裳。";
    }

    @Override
    protected String skill() {
        return "八卦阵法";
    }
}


继承者张

张飞呢,掌握了蜀军的经济大权,忙着呢,心里嘀咕我这还要杀猪还要训练新兵,训啥训啊,能打就行。

public class ZhangAbsShu extends AbstractShu {

    @Override
    String doIntroduce(Soldier soldier) {
        return "我" + soldier.getLocation() + soldier.getLastName() + soldier.getName() + "做好事从来不留姓名";
    }
}


测试

经过了短期的训练,我们来看看训练结果

public class Test {
    public static void main(String[] args) throws Exception {
        Soldier soldier = new Soldier("子龙", "赵", "常山");

        AbstractShu soldier4Guan = new GuanAbsShu();
        soldier4Guan.rule(soldier);

        System.out.println("\n------------------------------------\n");

        AbstractShu soldier4Zhang = new ZhangAbsShu();
        soldier4Zhang.rule(soldier);
    }
}

这里写图片描述

总结

通过上面这个栗子也看出如果蜀国招了新的大将来训练士兵,只需要继承AbstractShu再新加一些技能即可。
所以模板方法是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。是基于继承的代码复用的基本模式。【重要的话要说2遍】
更多模板方法文章请移步郭神Ak47卡奴达摩



【模板方法】与【策略模式】比较

【温馨提示】:如果你看完了策略模式,感觉知识有点混淆,可以直接看此段落。

模板方法要点
  • 定义算法步骤,子类实现具体算法逻辑。
  • 【好莱坞原则】,防止“依赖腐败”,高层组件对待底层组件的方式【别调用我!我会调用你!】
  • 为了防止子类改变模板中的算法,可以将模板方法声明为final
  • 策略模式和模板方法都封装算法,一个用组合,一个用继承。
  • 模板方法重在封装算法骨架。【同一个流程,中间的不同小插曲】
  • 策略模式重在分离并封装算法实现。【完成整套算法,不同实现类还可以相互替换】
  • 策略模式常用例子【不同节假日商品的不同折扣】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值