模板方法的概念
1、规定一个执行流程,所有对象的执行过程都依据这个流程
2、把所有对象中相同操作的步骤直接实现,封装在这个框架中
3、把因对象而异的操作交由具体的对象子类实现
模板方法举例
这里用学生体测举一个例子:
体测有多个不同项目,其中包括全部人都要测试的项目,也包括因人而异的项目,比如男生要测引体向上,而女生要测仰卧起坐。
在模板方法中,我们规定一个体测的具体流程,如先测身高体重(First),再测试跑步(Second),最合测试引体向上/仰卧起坐(Third)。
其中,测身高体重是男女都必需的测试,跑步和力量测试则是因性别而异的测试
综上所述,我们需要在模板方法中声明三个测试方法以及一个开始体测的方法,并在开始体测的方法中有序调用三个体测
代码示例
//模板方法基类 class abstract Test { //开始体测的方法,使用final修饰,让子类不可更改,以确保子类遵守这个流程 public final void startTest(){ FirstTest(); SecondTest(); ThirdTest(); } //测身高体重,所有学生相同的操作,直接实现 private void FirstTest(){ system.out.println("测试身高体重"); } //测试跑步,因性别而异,让子类实现 protected abstract void SecondTest(); //测试力量,因性别而异,让子类实现 protected abstract void ThirdTest(); }
//男学生测试类 class MaleTest extends Test { @Override protected void SecondTest(){ system.out.println("测试跑步1000米"); } @Override protected void ThirdTest(){ system.out.println("测试引体向上"); } }
//女学生测试类 class FemaleTest extends Test { @Override protected void SecondTest(){ system.out.println("测试跑步800米"); } @Override protected void ThirdTest(){ system.out.println("测试仰卧起坐"); } }
//示例 class TestDemo { public static void main(String[] args) { Test student1 = new MaleTest(); student1.startTest(); Test student2 = new FemaleTest(); student2.startTest(); } }扩展
上述过程大致上完成了正常的男女学生的体测流程,然而,在实际的体测中,并不是所有的学生都需要参加测试的,有部分学生可能由于身体条件或疾病的原因,是可以不参加测试的,那么这些学生按照上面的流程就走不通了,因此,我们需要对这个模板方法的体测流程进行改造
//模板方法基类 class abstract Test { //开始体测的方法,使用final修饰,让子类不可更改,以确保子类遵守这个流程 public final void startTest(){ FirstTest(); if (isNeedTest()) { SecondTest(); ThirdTest(); } } //测身高体重,所有学生相同的操作,直接实现 private void FirstTest(){ system.out.println("测试身高体重"); } //测试跑步,因性别而异,让子类实现 protected abstract void SecondTest(); //测试力量,因性别而异,让子类实现 protected abstract void ThirdTest(); //是否需要测试Second和Third protected boolean isNeedTest(){ return true; } }
如代码所示,我们增加了一个判断方法,用来判断学生是否需要参加跑步和力量测试,默认返回为true,如果返回false,则不走Second和Third的流程
新建一个特殊情况的测试对象类,重写isNeedTest方法,返回false
class SpecialTest extends Test { @Override protected void SecondTest(){ //不需要测试 system.out.println("此处不打印"); } @Override protected void ThirdTest(){ //不需要测试 system.out.println("此处不打印"); } @Override protected boolean isNeedTest(){ return false; } }
class TestDemo { public static void main(String[] args) { //男学生体测 Test student1 = new MaleTest(); student1.startTest(); //女学生体测 Test student2 = new FemaleTest(); student2.startTest(); //特殊情况,只测试身高体重 Test student3 = new SpecialTest(); student3.startTest(); } }当student3执行开始体测时,只会打印身高体重的测试,而不用再进行跑步和力量测试了