一、定义
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
二、使用场景
重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过子类方法约束其行为。
三、UML类图
AbstractClass:抽象类,定义了一套算法框架。
ConcreteClass:具体实现类。
四、实现
//抽象类
public abstract class AbstractClass {
public abstract void primitiveOperation1();
public abstract void primitiveOperation2();
public void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
}
//具体实现类A
public class ConcreteClassA extends AbstractClass {
@Override
public void primitiveOperation1() {
System.out.println("具体类A方法1实现");
}
@Override
public void primitiveOperation2() {
System.out.println("具体类A方法2实现");
}
}
//具体实现类B
public class ConcreteClassB extends AbstractClass {
@Override
public void primitiveOperation1() {
System.out.println("具体类B方法1实现");
}
@Override
public void primitiveOperation2() {
System.out.println("具体类B方法2实现");
}
}
//客户端
public class Client {
public static void main(String[] args) {
AbstractClass c;
c = new ConcreteClassA();
c.templateMethod();
c = new ConcreteClassB();
c.templateMethod();
}
}
五、应用
例子:Android AsyncTask
在使用AsyncTask时,我们都知道把耗时操作放在doInBackground方法中,在doInBackground之前,如果还想做一些类似的初始化操作,可以把实现写在onPreExecute方法中,当doInBackground方法执行完成后,会执行onPostExecute方法,而我们只需要构建AsyncTask对象,然后执行execute方法即可。我们可以看到,它整个执行过程其实是一个框架,具体的实现都需要子类来完成,而且它执行的算法框架是固定的,调用execute后会依次执行onPreExecute、doInBackground、onPostExecute,当然也可以通过onProgressUpdate来更新进度。
例子:Android Activity
Activity从启动到显示到窗口会经历如下过程:onCreate、onStart、onResume,如果我们想在某个生命周期方法中做一些操作,可以在子类中覆写相应的生命周期方法并实现相关的操作。这就是一个模板方法的应用。
六、总结
模板方法模式用4个字概括就是:流程封装。也就是把某个固定的流程封装到一个final方法中,并且让子类能够定制这个流程中的某些或者所有步骤,这就要求父类提取共用的代码,提升代码的复用率,同时也带来了更好的可扩展性。