模板方法模式
模板方法模式 Template Method
定义一个操作中的算法骨架,而将一些步骤延伸到子类中去,使得子类可以不改变一个算法的结构,即可重新定义该算法的某些特定步骤。
这里需要复用的是算法的结构,也就是步骤,而步骤的实现可以在子类中完成。
使用场合
1.一次性实现一个算法的不变部分,并且将可变的行为留给子类来完成。
2.各子类公共的行为应该被提取出来并集中到一个公共父类中以避免代码的重复。
首先识别现有代码的不同之处,并且把不同部分分离为新的操作,最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3.控制子类的扩展。
模板方法模式的组成
父类角色:提供模板
子类角色:为模板提供实现。
代码例子
下面是一个简单的模板方法模式的代码例子:
首先,定义父类,规定了几个抽象的方法,和模板方法,其中包含了对抽象方法的调用,并且规定了顺序:
package com.meng.designpattern.templatemethod; public abstract class AbstractClass { public void template() { // 父类规定了做事情的顺序(定义了算法骨架) this.method1(); this.method2(); this.method3(); } // 具体做的实现由子类完成 public abstract void method1(); public abstract void method2(); public abstract void method3(); }
然后,子类继承父类,实现抽象方法:
package com.meng.designpattern.templatemethod; public class ConcreteClass extends AbstractClass { public ConcreteClass() { } @Override public void method1() { System.out.println("Step 1"); } @Override public void method2() { System.out.println("Step 2"); } @Override public void method3() { System.out.println("Step 3"); } }
调用时使用父类接口,但是建立子类对象:
package com.meng.designpattern.templatemethod; public class Client { public static void main(String[] args) { AbstractClass ac = new ConcreteClass(); ac.template(); } }
程序输出:
Step 1
Step 2
Step 3
可以看到虽然具体实现是由子类完成,但是方法调用的顺序是按照父类规定的来完成的。
JUnit中的模板方法模式体现
以JUnit3为例,JUnit3中,所有的测试类都要继承于TestCase,这个基类中规定了方法调用的顺序,所以每次测试时都是先执行setUp(),再执行测试方法,最后执行tearDown()。
可以查看JUnit3的源代码:
/** * Runs the bare test sequence. * * @exception Throwable * if any exception is thrown */ public void runBare() throws Throwable { setUp(); try { runTest(); } finally { tearDown(); } }