TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
package com.itachi.beans;
public abstract class TemplateMethod {
//链式初始化器.
public final void init() {
//code.
onInit();
}
/*此方法由子类实现.
如果此步骤对于子类是必须的,使用抽象方法,
如果此步骤对于子类并不是必须的,可以使用钩子方法.
*/
protected abstract void onInit();
//模板方法.
public final void core() {
first();
second();
third();
fourth();
}
//留待子类实现.
protected abstract void first();
private void second(){
// code.
onSecond();
}
//留待子类实现.
protected abstract void onSecond();
//留待子类实现.
protected abstract void third();
private void fourth(){
a();
b();
c();
}
private void a(){
//code.
}
private void b(){
//code.
}
private void c(){
//code.
}
//链式销毁器.
public final void destroy() {
// code.
onDestroy();
}
//这是一个钩子方法,子类根据情况选择是否重写此方法.
protected void onDestroy(){
}
}
[/code] 什么是模板方法:init,core,destroy这样的方法就是模板方法.
模板方法的目的:分离出公共部分放在父类,不同的部分由子类实现.模板方法是类暴露给外部的接口,被其它类调用.
模板方法的结构:方法本身是对一系列执行步骤的封装,每一步骤的具体执行可能有变化,由其子类实现,一些步骤本身也可能是一个模板方法,如second()方法,将公共代码放入second()方法中,不同的部分由子类实现.
fourth()方法是一个模板方法吗?fourth()并不是模板方法,看理解的角度,如果认为封装步骤分解的方法就是模板方法,它就是,如果在此基础上要加上"需要出现在继承体系中"的限定条件,那它就不是.
回调接口实现类中的所实现接口中定义的方法往往也是一个模板方法. 对于TemplateMethod类也可以进行重构,提炼超接口,将类中的模板方法移动到超接口中.这将得到和回调接口相似的结构.
可以这样做,但未必一定要这样做.是否进行此重构的标准在于core()方法级别的实现是否有变化,如果只有一个流程那么就没必要提炼,如果有多于一个流程,流程之间相似但不相同,那么应该进行提炼,
使用接口表达相似的部分,实现类表达不同的部分。
抽象级别的讨论,关注方法的抽象级别: 方法的抽象级别与分析过程中问题划分粒度相一致.
init,core,destroy它们的抽象级别是一致的,是相对于这个类所解决问题的顶级分解; first,second,third,fourth是一致的,这些是对core所解决问题的步骤分解; a,b,c是一致的,
根据访问修饰符也很清晰的表达出了方法的针对性,public就是针对外部接口, protected是暴露给子类的接口, private封装内部实现.
最终得到了什么:清晰性.
难点:如何找到相同或相似的流程,如何控制方法的抽象级别.
没有写到的讨论:
1.重写钩子方法与重写普通的实现方法的差异.
2.模板方法模式与Strategy模式的关于继承与组合的讨论.(这个是经典讨论). |
|