模板方法模式TemplateMethod,定义一个操作中的算法的骨架,而将一些操作步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法的结构图:
AbstractClass 是抽象类,其实也就是一个抽象模板,定义并实现了一个模板方法,这个模板方法通常是一个具体方法,他给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
abstract class AbstractClass{
//一些抽象行为,放到子类去实现
public abstract void primitiveOperation1();
public abstract void primitiveOperation2();
//模板方法,给出了逻辑的骨架,而逻辑的组成是一些抽象的操作,他们都被推迟到子类实现
public void TemplateMethod(){
primitiveOperation1();
primitiveOperation2();
//这里可以是一些共有的代码
}
}
ConcreteClass 实现父类定义的一个或多个方法,每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法(就是顶级逻辑的组成步骤)的具体实现,从而使得顶级逻辑的实现各不相同。
class ConcreteClassA : AbstractClass{
public void primitiveOperation1(){
//具体类A的方法实现
}
public void primitiveOperation2(){
//具体类A的方法实现
}
}
class ConcreteClassB : AbstractClass{
public void primitiveOperation1(){
//具体类B的方法实现
}
public void primitiveOperation2(){
//具体类B的方法实现
}
}
//客户端的代码
static void main(String[] args){
AbstractClass ac;
ac = new ConcreteClassA();
ac.TemplateMethod();
ac = ConcreteClassB();
ac.TemplateMethod();
}
小时候,老师做课堂测试,会在黑板上写题目,然后要学生先抄题目,在做答案。我们以这个实例来看下模板方法模式怎么用。
package template.method;
public abstract class TestPaper {
public abstract String answer1();
public abstract String answer2();
public void testQuestion1(){
System.out.println("第一道测试题:*****,答案:"+answer1());
}
public void testQuestion2(){
System.out.println("第二道测试题:######,答案:"+answer2());
}
}
@Override
public String answer1() {
String mStr = "学生A对问题1的回答!";
return mStr;
}
@Override
public String answer2() {
String mStr = "学生A对问题2的回答!";
return mStr;
}
}
public class StudentBTestPaper extends TestPaper {
@Override
public String answer1() {
String mStr = "学生B对问题1的回答!";
return mStr;
}
@Override
public String answer2() {
String mStr = "学生B对问题2的回答!";
return mStr;
}
}
客户端代码:
public class TestPaperAnswer {
public static void main(String[] args){
TestPaper studentA = new StudentATestPaper();
studentA.testQuestion1();
studentA.testQuestion2();
TestPaper studentB = new StudentBTestPaper();
studentB.testQuestion1();
studentB.testQuestion2();
}
}
输出结果:
第一道测试题:*****,答案:学生A对问题1的回答!
第二道测试题:######,答案:学生A对问题2的回答!
第一道测试题:*****,答案:学生B对问题1的回答!
第二道测试题:######,答案:学生B对问题2的回答!
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来实现它的优势。模板方法模式就是提供了一个很好的代码复用平台。有时候,我们会遇到由一系列构成的过程需要执行,这个过程从高层次看是相同的,但是有些步骤的实现可能不同,这时候就应该考虑使用模板方法模式了。
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,通过模板方法模式把这些行为搬移到单一的地方,这样就帮子类摆脱重复的不变行为的纠缠。