模板方法模式 (Template Method)
特点:
- 1.定义了一个操作中的算法骨架,而将部分步骤的实现在子类中完成。模板方法模式使得子类可以不 变一个算法的结构即可重定义该算法的某些特定步骤。
- 2.它是基于继承的代码复用的基本技术,没有关联关系,因此在模板方法模式的类图中,只有继承关系
- 3.模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤
- 4.代表这些具体逻辑步骤的方法称作基本方法(primitive method);而将这些基本方法汇总起来的方法叫做模板方法(template method),这个设计模板的名字就是从此而来
模板方法模式:定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现,新子类在不改变一个算法结构的前提下重新定义某些特定步骤的算法
核心:处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定,因此我们采用工厂方法模式,将这个节点的代码实现转移给子类完成。即:处理步骤父类中定义好,具体实现延迟到子类中定义。
基本代码结构:
abstract class AbstractClass {
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
public void TemplateMethod() {
PrimitiveOperation1();
PrimitiveOperation2();
}
}
class ConcreteClassA extends AbstractClass {
@Override
public void PrimitiveOperation1() {
System.out.println("具体A类方法1");
}
@Override
public void PrimitiveOperation2() {
System.out.println("具体A类方法2");
}
}
class ConcreteClassB extends AbstractClass {
@Override
public void PrimitiveOperation1() {
System.out.println("具体B类方法1");
}
@Override
public void PrimitiveOperation2() {
System.out.println("具体B类方法2");
}
}
class ConcreteClassB extends AbstractClass { @Override public void PrimitiveOperation1() { System.out.println("具体B类方法1"); } @Override public void PrimitiveOperation2() { System.out.println("具体B类方法2"); } }
public class TemplateMethodPattern { public static void main(String[] args) {
AbstractClass objA = new ConcreteClassA();
AbstractClass objB = new ConcreteClassB();
objA.TemplateMethod();
objB.TemplateMethod();
}
}
基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
● 抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字标示。
● 具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。
● 钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。
实例代码:
public abstract class BankTemplateMethod {
public void takeNum(){
System.out.println("排队取号");
}
public void evaluate(){
System.out.println("反馈评分");
}
public abstract void transact (); //办具体的银行业务,钩子方法
//模板方法,把基本操作组合到一起,子类一般不能重写
public final void process(){
this.takeNum();
this.transact(); //钩子方法,执行时,挂哪个子类的方法就调用哪个
this.evaluate();
}
}
JDK中模板方法模式的使用
- java.io.InputStream, java.io.OutputStream, java.io.Reader 以及 java.io.Writer 中所有非抽象方法。
- java.util.AbstractList, java.util.AbstractSet 以及 java.util.AbstractMap中所有非抽象方法。
- 模板方法模式应用场景
- 实现一个算法时,整体步骤很固定,某些部分易变,易变部分可以抽象成出来,供子类实现
- 1.数据库的访问的封装
- 2.servlet中doGet和doPost方法调用
- 3.Hibernate中模板程序
- 4.spring中JDBCTemplate和HibernateTemplate等
-
重要提示
- 模板方法应该是由确定的步骤组成。这些步骤的顺序是固定的。基类与子类之间某些方法或者实现可以有所不同。模板方法应该是final的。大多时候,子类的调用的方法是来自于超类。但是在模板模式中,超类的模板方法调用的方法却来至于子类,这就是著名的Hollywood原则-“don’t call us, we’ll call you”。
- 基类方法的默认实现被退化为钩子Hooks的概念,他们被设计在子类中被重写,如果你期望一些方法在子类中不被重写,你可以让他们为final。