设计模式学习笔记(二)——模板方法模式
一、概述
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
二、实现模板方法模式
2.1、模板方法模式定义
这里我们以一个老师模板为示例,老师是一个抽象的对象,老师有sayHello方法,上课方法(study),但是老师又分很多种类型,有英语、语文、数学等老师,但是他们工作的方法步骤都是相同的,只是步骤中的细节是不相同,英语老师有他的sayHello方式,上课方式,语文、数学老师也同样有他们各自的方式,但是工作的结构是相同的。
抽象的老师模板(TeacherTemplate):定义老师操作的算法骨架,定义固定的步骤,由子类去继承去实现各个步骤。自身通常会写一个templateMethod(模板方法)去调用行为,此模板方法是唯一的。
具体英语老师(EnglishTeacher):继承抽象的老师模板,实现方法,定义自己的逻辑步骤。
具体数学老师(MathTeacher):和具体英语老师同理。
2.2、模板方法模式实现
抽象的老师模板(TeacherTemplate):
/**
* 抽象的老师模板
* @author Administrator
*
*/
public abstract class TeacherTemplate {
/**
* sayHello方法
*/
protected abstract void sayHello();
/**
* 学习方法
*/
protected abstract void study();
/**
* 模板方法
*/
public final void templateMethod() {
sayHello();
study();
}
}
具体英语老师(EnglishTeacher):
/**
* 具体的英语老师
* @author Administrator
*
*/
public class EnglishTeacher extends TeacherTemplate {
@Override
protected void sayHello() {
System.out.println("EnglishTeacher: Hello!");
}
@Override
protected void study() {
System.out.println("EnglishTeacher 上英语课.");
}
}
具体的数学老师(MathTeacher):
/**
* 具体的数学老师
* @author Administrator
*
*/
public class MathTeacher extends TeacherTemplate {
@Override
protected void sayHello() {
System.out.println("数学老师: 你好!");
}
@Override
protected void study() {
System.out.println("数学老师 上数学课.");
}
}
测试客户端:
public class TeacherClient { public static void main(String[] args) { // 创建英语老师 TeacherTemplate englishTeacher = new EnglishTeacher(); // 创建数学老师 TeacherTemplate mathTeacher = new MathTeacher(); // 调用模板方法 englishTeacher.templateMethod();
System.out.println("==================================="); mathTeacher.templateMethod(); } }
运行结果:
三、总结
优点:
1.父类封装不变部分,扩展可变部分;不变部分的算法封装到父类中实现(模板方法),而可变部分则通过继承,子类来扩展(具体实现)。
2.提取公共部分代码,便于维护。
3.存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合"开闭原则"。行为由父类控制,子类实现。
缺点:
1.每个不同的实现类都要定义一个子类,会导致类增多,系统更加庞大。
2.子类的执行结果影响了父类的结果,会增加代码的阅读的难道。
适用性:
模板方法模式应用于下列情况:
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类去实现。
2.各子类中公共的行为应被提取出来并集中到一个公共类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。