在面向对象开发过程中,通常会遇到这样一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是,某些步骤的具体实现是位置,或者说是这些步骤的实现是会随着环境的变化而改变的,例如,执行程序的流程大致如下。
(1).检查代码的正确性
(2)链接相关的类库
(3)编译相关代码
(4)执行程序
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法结构即可重定义该算法的某些特定步骤。
(说白了就是告诉你一定要做几件事,但是怎么做就看你自己了)
(1)多个子类有公用的方法,并且逻辑基本相同时
(2)重要,复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
(3)重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过子函数约束其行为。
//AbstractComputer.java
/** * Created by Administrator on 2016/5/11 0011. */ public abstract class AbstractComputer { protected void powerOn(){ System.out.println("开启电源"); } protected void checkHardware(){ System.out.println("硬件检查"); } protected void loadOS(){ System.out.println("载入操作系统"); } protected void login(){ System.out.println("小白的计算机无验证,直接进入系统"); } /** * 启动计算机方法,步骤固定为开启电源,系统检查,加载操作系统,用户登录。该方法为final,防止算法框架被覆写 * */ public final void startUp(){ System.out.println("-----关机 START------"); powerOn(); checkHardware(); loadOS(); login(); System.out.println("-----关机 END------"); } }
//CoderComputer.java
/** * Created by Administrator on 2016/5/11 0011. */ public class CoderComputer extends AbstractComputer{ @Override protected void login() { super.login(); System.out.println("程序员只需要进行用户和密码验证就可以了"); } }
//MilitaryComputer.java
/** * Created by Administrator on 2016/5/11 0011. */ public class MilitaryComputer extends AbstractComputer { @Override protected void checkHardware() { super.checkHardware(); System.out.println("检查硬件防火墙"); } @Override protected void login() { super.login(); System.out.println("进行指纹识别等复杂的用户验证"); } }
//Test.java
/** * Created by Administrator on 2016/5/11 0011. */ public class Test { public static void main(String[] args){ AbstractComputer comp = new CoderComputer(); comp.startUp(); comp = new MilitaryComputer(); comp.startUp(); } }
Startup(powerOn--->check--->loadOs---->login)
从上面的例子可以看到,在StartUp方法中有一些固定的步骤,初次为开启电源,检查硬件,加载系统,用户登录四个步骤
不同用户的这几个步骤的实现可能各不相同,因此子类需要复写相应的方法来实现自定义处理
在Android中AsyncTask是比较常用的一个类型,这个类就使用了模板方法模式。
Execute--->onPreExecute---->doinBackgroud------>onPostExecute
待添加?????
模板方法模式用4个字概括就是:流程封装。也就是把某个固定的流程封装到一个final函数中,并且让子类能够定制这个流程中的某些或者所有步骤,这就要求父类提取共用的代码,提升代码的复用率,同时也带来了更好的可扩展性
(1)封装不变部分,扩展可变部分
(2)提取公共部分代码,便于维护
模板方法会带来代码阅读的难度,会让用户觉得难以理解