1. 什么是模板方法模式?
在父类中定义处理流程的框架,在子类中实现具体的处理。
从字面上理解,模板方法模式是带有模板功能的模式,而组成模板的方法被定义在父类中。这些方法基本上都是抽象方法,模板只是规定了处理的流程或者步骤。
子类实现了这些抽象方法的具体处理,在不同的子类中实现不同的具体处理,当父类的模板方法被调用时也就有不同的具体实现。但是,无论子类的具体实现是怎样的,处理流程都会按照父类中所定义的进行。
2. 模板方法模式中的角色
模板方法模式相对比较简单,只有两个角色
- AbstractClass(抽象类)
AbstractClass主要负责实现模板方法,以及声明在模板方法中是用到的抽象方法,这些抽象方法有ConcreteClass实现。如果模板方法中的某些方法具有共同的行为,那么AbstractClass也负责实现这行行为。 - ConcreteClass(具体类)
ConcreteClass负责具体实现AbstractClass中定义的抽象方法,这些方法将会在AbstractClass的模板方法中被调用。
3. 示例代码
为了方便理解,写一个简单的程序来直观的演示一下模板方法模式。
程序是模拟把动物放进冰箱的操作,除了著名的把大象放进冰箱,我们再增加一个把猪放进冰箱。
抽象类
public abstract class AnimalRefrigerator {
/**
* 所有子类共同的行为,所有在父类就实现
*/
public void open() {
System.out.println("把冰箱门打开。");
}
/**
* 不同的子类有不同的实现,所以定义成抽象方法,具体实现交给子类。
*/
public abstract void put();
/**
* 所有子类共同的行为,所有在父类就实现
*/
public void close() {
System.out.println("把冰箱门关上。");
}
/**
* 模板方法,规定了把动物放进冰箱的流程
* 1.open() 把冰箱门打开
* 2.put() 把动物放进冰箱
* 3.close() 把冰箱门关上
*/
public final void work() {
open();
put();
close();
}
}
具体类
public class PigRefrigerator extends AnimalRefrigerator {
@Override
public void put() {
System.out.println("把猪放进冰箱里。");
}
}
public class ElephantRefrigerator extends AnimalRefrigerator {
@Override
public void put() {
System.out.println("把大象放进冰箱里。");
}
}
Test类
public class Test {
public static void main(String[] args) {
AnimalRefrigerator pig = new PigRefrigerator();
System.out.println("把猪放进冰箱分为几步:");
pig.work();
AnimalRefrigerator elephant = new ElephantRefrigerator();
System.out.println("把大象放进冰箱分为几步:");
elephant.work();
}
}
运行结果:
4. 总结
- 如果使用模板方法模式,当我们在模板方法里发现bug时,只需要修改模板方法就能解决问题。
- 在子类实现父类中声明的抽象方法时,必须要理解这行方法被调用的时机。
- 使用父类类型的变量保存子类实例的有点:即使不用instanceof等指定子类的类型,程序也能正常运行。
- 父类和子类相互协作支撑了整个程序。在抽象类阶段确定处理流程很重要,如果把过多的方法的具体实现放在父类,会降低子类的灵活性;反之,如果子类需要实现的方法过多,就会造成子类臃肿并且增加了出现bug的几率。