目录
一、前言
二、模板模式
三、带钩子的模板模式
四、总结
一、前言
模板方法模式是一种行为型设计模式,它定义了一个操作中的算法框架,将一些步骤延迟到子类中实现。这种模式是基于“开闭原则”的设计思想,即对扩展开放,对修改关闭。
模板方法模式的核心思想是:定义一个抽象类,把一些抽象行为留给子类去实现,而把一些公共行为放在抽象类中实现。在模板方法模式中,抽象类中定义了一个算法框架,由具体子类来实现其中的具体步骤。
模板方法模式一般由以下几个角色组成:
- 抽象类(Abstract Class):定义了一个算法框架,其中包含了一些抽象的操作,由子类去实现。
- 具体类(Concrete Class):实现了抽象类中定义的抽象方法,完成算法中的具体步骤。
类图大致结构:
二、模板方法模式
比如学生进行考试,每个人的试卷都是一致的,具体的不一致是每个人的答案,这时候我们可以将试卷当做一个抽象模板,每个学生的答案就是具体的一个实现。
试卷模板类ExamPaperTemplate:
public abstract class ExamPaperTemplate {
public abstract String Answer1();
public abstract String Answer2();
public abstract String Answer3();
private void Question1(){
System.out.println(String.format("1+1=%s", Answer1()));
}
private void Question2(){
System.out.println(String.format("1+2=%s", Answer2()));
}
private void Question3(){
System.out.println(String.format("1+3=%s", Answer3()));
}
public void TemplateMethod(){
Question1();
Question2();
Question3();
}
}
学生StudentConcrete1、StudentConcrete2类:
public class StudentConcrete1 extends ExamPaperTemplate{
@Override
public String Answer1() {
return "2";
}
@Override
public String Answer2() {
return "3";
}
@Override
public String Answer3() {
return "4";
}
}
public class StudentConcrete2 extends ExamPaperTemplate{
@Override
public String Answer1() {
return "11";
}
@Override
public String Answer2() {
return "22";
}
@Override
public String Answer3() {
return "33";
}
}
客户端调用类TemplateClient:
public class TemplateClient {
public static void main(String[] args) {
ExamPaperTemplate examPaperTemplate1 = new StudentConcrete1();
examPaperTemplate1.TemplateMethod();
ExamPaperTemplate examPaperTemplate2 = new StudentConcrete2();
examPaperTemplate2.TemplateMethod();
}
}
运行结果:
三、带钩子的模板模式
模板模式中还有一类是带钩子的,通过钩子,子类可以选择性对父类执行。也用之前的代码展示,只是加上钩子,具体可以理解为试卷中包含附加题,可选择不做,包含建议,可选择不写建议。
public abstract class ExamPaperTemplate {
public abstract String Answer1();
public abstract String Answer2();
public abstract String Answer3();
public abstract String Answer4();
public abstract String Answer5();
private void Question1(){
System.out.println(String.format("1+1=%s", Answer1()));
}
private void Question2(){
System.out.println(String.format("1+2=%s", Answer2()));
}
private void Question3(){
System.out.println(String.format("1+3=%s", Answer3()));
}
private void Question4(){
System.out.println(String.format("1*1=%s", Answer4()));
}
/**
* 钩子方法,子类覆盖
*/
private void Question5(){
System.out.println(String.format("建议:%s", Answer5() == null ? "无" : Answer5()));
}
/**
* 钩子方法,子类选择性执行
*/
boolean customer(){
return true;
}
public void TemplateMethod(){
Question1();
Question2();
Question3();
if (customer()){
Question4();
}
Question5();
}
}
public class StudentConcrete1 extends ExamPaperTemplate{
@Override
public String Answer1() {
return "2";
}
@Override
public String Answer2() {
return "3";
}
@Override
public String Answer3() {
return "4";
}
@Override
public String Answer4() {
return null;
}
@Override
public String Answer5() {
return null;
}
@Override
boolean customer(){
return false;
}
}
public class StudentConcrete2 extends ExamPaperTemplate{
@Override
public String Answer1() {
return "11";
}
@Override
public String Answer2() {
return "22";
}
@Override
public String Answer3() {
return "33";
}
@Override
public String Answer4() {
return "1";
}
@Override
public String Answer5() {
return "题目太简单";
}
}
public class TemplateClient {
public static void main(String[] args) {
ExamPaperTemplate examPaperTemplate1 = new StudentConcrete1();
examPaperTemplate1.TemplateMethod();
System.out.println("============");
ExamPaperTemplate examPaperTemplate2 = new StudentConcrete2();
examPaperTemplate2.TemplateMethod();
}
}
运行结果:
四、总结
实际开发中,像Spring框架中的JdbcTemplate和HibernateTemplate就是典型的模板方法模式的应用,游戏开发中也使用得很多,比如角色的行走、攻击等操作。