模板方法(Template Method DP):在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。子类可以在不改变算法结构的前提下,重新定义算法的某些步骤。
模板方法的实现是通过钩子(Hooks)。什么是钩子呢?
钩子是一种被声明在超类中的方法,只有空的或者默认的实现,其存在的意义就是让子类改写的。
我想到的最典型的例子:安卓开发的Activity,各种onCreate,onResume,onDestroy方法都是钩子,子类可以很方便地加入自己的东西,因此Activity很明显采用了模板方法。
什么是模板?超类的算法或者实现就是模板。实际生活当中我们也用过模板,模板就是拿过来改改用的。全部照抄不叫模板,全部推翻也不叫模板。
这里又可以和策略模式还有工厂方法比较一下。从概念上来讲其实差别很明显,策略模式是对同一方法的不同实现的封装,模板是子类来决定如何实现一个算法或者流程,工厂方法是子类决定实例化具体类。
代码:
行窃方法,是一个模板,留下3个钩子函数,分别是挑目标,迷惑目标,偷得物品:
/**
*
* StealingMethod defines skeleton for the algorithm.
*
*/
public abstract class StealingMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(StealingMethod.class);
protected abstract String pickTarget();
protected abstract void confuseTarget(String target);
protected abstract void stealTheItem(String target);
/**
* Steal
*/
public void steal() {
String target = pickTarget();
LOGGER.info("The target has been chosen as {}.", target);
confuseTarget(target);
stealTheItem(target);
}
}
选择老弱的哥布林女性,Hit&Run方法,抢了就跑:
/**
*
* HitAndRunMethod implementation of {@link StealingMethod}.
*
*/
public class HitAndRunMethod extends StealingMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(HitAndRunMethod.class);
@Override
protected String pickTarget() {
return "old goblin woman";
}
@Override
protected void confuseTarget(String target) {
LOGGER.info("Approach the {} from behind.", target);
}
@Override
protected void stealTheItem(String target) {
LOGGER.info("Grab the handbag and run away fast!");
}
}
选择小商人,哭着跑向目标,拥抱然后掏包:
/**
*
* SubtleMethod implementation of {@link StealingMethod}.
*
*/
public class SubtleMethod extends StealingMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(SubtleMethod.class);
@Override
protected String pickTarget() {
return "shop keeper";
}
@Override
protected void confuseTarget(String target) {
LOGGER.info("Approach the {} with tears running and hug him!", target);
}
@Override
protected void stealTheItem(String target) {
LOGGER.info("While in close contact grab the {}'s wallet.", target);
}
}
半成年人盗贼,使用行窃方法模板来偷东西:
/**
*
* Halfling thief uses {@link StealingMethod} to steal.
*
*/
public class HalflingThief {
private StealingMethod method;
public HalflingThief(StealingMethod method) {
this.method = method;
}
public void steal() {
method.steal();
}
public void changeMethod(StealingMethod method) {
this.method = method;
}
}
测试:
public static void main(String[] args) {
HalflingThief thief = new HalflingThief(new HitAndRunMethod());
thief.steal();
thief.changeMethod(new SubtleMethod());
thief.steal();
}
其实这里也使用了策略模式,所以可以实时切换。模板方法本身是不带这个功能的。