定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法结构即可重定义该算法的某些特征步骤。
模板方法模式巧妙地结合了抽象类虚部方法与实部方法,分别定义了可变部分与不变部分,其中前者留给子类去实现,保证了系统的可扩展性;而后者则包含一系列对前者的逻辑调用,为子类提供了一种固有的应用指导规范,从而达到虚中带实、虚实结合的状态。
例如课程表,每周5天课,不同年级学生学的课程是不同的。
那么咱们就通过模板方法来实现高二高三的课表内容。
public abstract class Timetable {
public abstract void Mon();
public abstract void Tue();
public abstract void Wed();
public abstract void Thur();
public abstract void Fri();
public final void TimetableSchedule(){
Mon();
Tue();
Wed();
Thur();
Fri();
}
}
public class GradeTwo extends Timetable{
@Override
public void Mon() {
System.out.println("Mon:高二语文");
}
@Override
public void Tue() {
System.out.println("Tue:高二数学");
}
@Override
public void Wed() {
System.out.println("Wed:高二物理");
}
@Override
public void Thur() {
System.out.println("Thur:高二生物");
}
@Override
public void Fri() {
System.out.println("Fri:高二英语");
}
}
public class GradeThree extends Timetable{
@Override
public void Mon() {
System.out.println("Mon:高三语文");
}
@Override
public void Tue() {
System.out.println("Tue:高三数学");
}
@Override
public void Wed() {
System.out.println("Wed:高三物理");
}
@Override
public void Thur() {
System.out.println("Thur:高三生物");
}
@Override
public void Fri() {
System.out.println("Fri:高三英语");
}
}
public class Client {
public static void main(String[] args) {
GradeThree gradeThree = new GradeThree();
GradeTwo gradeTwo = new GradeTwo();
gradeThree.TimetableSchedule() ;
gradeTwo.TimetableSchedule() ;
}
}
高考越来越近,学校要求在校生班级每周六补课,那么就要将高三的课表增加周六的课程内容。因此,除了模板方法改动外,高二高三班级的课表还要实现周六的课程内容。
public abstract class Timetable {
public abstract void Mon();
public abstract void Tue();
public abstract void Wed();
public abstract void Thur();
public abstract void Fri();
public abstract void Sat();
public final void TimetableSchedule(){
Mon();
Tue();
Wed();
Thur();
Fri();
Sat();
}
}
public class GradeTwo extends Timetable{
@Override
public void Mon() {
System.out.println("Mon:高二语文");
}
@Override
public void Tue() {
System.out.println("Tue:高二数学");
}
@Override
public void Wed() {
System.out.println("Wed:高二物理");
}
@Override
public void Thur() {
System.out.println("Thur:高二生物");
}
@Override
public void Fri() {
System.out.println("Fri:高二英语");
}
@Override
public void Sat(){
System.out.println("Sat: 高二数学");
}
}
优点:
1、利用模板方法将模板方法的代码放到抽象父类中,可以提高代码的复用性。
2、将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。
缺点:
1、类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
2、类数量的增加,间接地增加了系统实现的复杂度。
3、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。