模板方法模式
模板方法模式,定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。
结构图
代码实现
抽象类AbstractClass:
/**
* 算法的骨架
* @author xukai
* 2016年3月14日 下午9:16:20
*/
public abstract class AbstractClass {
public abstract void primitiveOperation1();
public abstract void primitiveOperation2();
public void templateMethod(){
primitiveOperation1();
primitiveOperation2();
}
}
具体类ConcreteClass:
/**
* 实现类
* @author xukai
* 2016年3月14日 下午9:18:48
*/
public class ConcreteClass extends AbstractClass {
@Override
public void primitiveOperation1() {
System.out.println("具体类方法1实现");
}
@Override
public void primitiveOperation2() {
System.out.println("具体类方法2实现");
}
}
客户端:
/**
* 实现类
* @author xukai
* 2016年3月14日 下午9:18:48
*/
public class ConcreteClass extends AbstractClass {
@Override
public void primitiveOperation1() {
System.out.println("具体类方法1实现");
}
@Override
public void primitiveOperation2() {
System.out.println("具体类方法2实现");
}
}
控制台输出:
具体类方法1实现
具体类方法2实现
分析:模板方法模式是通过吧不变的行为搬移到超类,去掉子类重复代码。
demo
问题:复制试卷题目代码实现
抽象类:试卷类Paper
/**
* 试卷类,包含题目
* @author xukai
* 2016年3月14日 下午9:34:58
*/
public abstract class Paper {
protected String name = "学生姓名";
public void question1(){
System.out.println("金木研是不是很帅?");
System.out.println(name + "答案为:" + answer1());
}
public void question2(){
System.out.println("徐凯是不是很帅?");
System.out.println(name + "答案为:" + answer2());
}
public void question3(){
System.out.println("徐凯是不是比金木研帅?");
System.out.println(name + "答案为:" + answer3());
}
/**
* 子类重写方法,即答案
* @return
*/
public abstract String answer1();
public abstract String answer2();
public abstract String answer3();
}
学生A抄写试卷
public class StudentAPaper extends Paper {
public StudentAPaper(String name) {
super.name = name;
}
@Override
public String answer1() {
return "YES";
}
@Override
public String answer2() {
return "YES";
}
@Override
public String answer3() {
return "YES";
}
}
学生B抄写试卷并作答
public class StudentBPaper extends Paper {
public StudentBPaper(String name) {
super.name = name;
}
@Override
public String answer1() {
return "NO";
}
@Override
public String answer2() {
return "NO";
}
@Override
public String answer3() {
return "YES";
}
}
客户端测试
public class TemplateMethodTest {
public static void main(String[] args) {
Paper paper;
paper = new StudentAPaper("学生A");
paper.question1();
paper.question2();
paper.question3();
paper = new StudentBPaper("学生B");
paper.question1();
paper.question2();
paper.question3();
}
}
控制台输出:
金木研是不是很帅?
学生A答案为:YES
徐凯是不是很帅?
学生A答案为:YES
徐凯是不是比金木研帅?
学生A答案为:YES
金木研是不是很帅?
学生B答案为:NO
徐凯是不是很帅?
学生B答案为:NO
徐凯是不是比金木研帅?
学生B答案为:YES
总结
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬移到单一的地方,帮助子类摆脱重复的不变行为的纠缠。模板方法模式的结构
抽象方法
由抽象类声明不加以实现。定义好规范,然后由子类去实现。
模板方法
由抽象类声明并加以实现。一般来说,模板方法调用抽象方法来完成主要的逻辑功能,并且,模板方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被重写。
钩子方法
由抽象类声明并加以实现。但子类可以扩张,子类可以通过扩展钩子方法来影响模板方法的逻辑。(
违反里氏替换原则)