概要
在开发过程中,通常会遇到这样的问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是某些步骤的具体实现是未知的,或者说某些步骤的实现是会随着环境的变化而改变的。例如在创建Activity时,执行findView()、initData()、initUI()、setLisenter(),对于不同的Activity,上述步骤的执行结果是不一样的,但是执行流程是可以固定的。此类问题的解决方式之一就是使用模版方法模式。
定义
定义一个操作中的算法的框架,而一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤。
使用场景
- 多个子类有公有的方法,并且逻辑基本相同
- 重要复杂的算法,可以把核心算法设计为模版方法,周边相关细节功能则由各个子类实现。
- 重构时,模版方法模式是一个经常使用的模式,把相同的方法抽取到父类中,然后通过构子函数约束其行为。
UML类图
示例代码
创建模版方法
public abstract class AbsActivity {
void findView() {
System.out.println("findView");
}
void initData() {
System.out.println("initData");
}
void initUI() {
System.out.println("initUI");
}
void setLestener() {
System.out.println("setLestener");
}
public final void onCreate() {
System.out.println("创建Activity -- Start");
findView();
initData();
initUI();
setLestener();
System.out.println("创建Activity -- End");
}
}
创建具体实现类 OneActivity和TwoActivity
public class OneActivity extends AbsActivity {
@Override
void initData() {
System.out.println("OneActivity - initData");
}
@Override
void initUI() {
super.initUI();
System.out.println("标题设置为OneActivity");
}
}
public class TwoActivity extends AbsActivity {
@Override
void initUI() {
super.initUI();
System.out.println("标题设置为TwoActivity");
}
@Override
void setLestener() {
super.setLestener();
System.out.println("单击按钮-finish,将此Activity关闭");
}
}
测试类
public class Test {
public static void main(String[] args) {
AbsActivity oneActivity = new OneActivity();
AbsActivity twoActivity = new TwoActivity();
oneActivity.onCreate();
twoActivity.onCreate();
}
}
测试Log
创建Activity -- Start
findView
OneActivity - initData
initUI
标题设置为OneActivity
setLestener
创建Activity -- End
创建Activity -- Start
findView
initData
initUI
标题设置为TwoActivity
setLestener
单击按钮-finish,将此Activity关闭
创建Activity -- End
从上述代码可以看出,不同的实现子类按照步骤实现可能各不相同,因此子类只需要重写相应的方法来进行自定义处理。但是,注意onCreate()方法用final修饰符修饰,为了确保子类不能重写此方法。这样,子类只能通过改变某一步骤中的具体实现,而不能修改逻辑,保证了逻辑的稳定性。