适用环境:一次性实现一个算法的不变部分,并将可变行为留给子类来实现。各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。控制子类的拓展。对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。
实际应用:模板方法模式广泛应用于框架设计(如Spring、Struts等)中,以确保父类控制处理流程的逻辑顺序。
其结构中只存在父类和子类之间的继承关系。模板方法模式是最简单的行为型模式,在其抽象类中定义了一个称为模板方法的方法,在这个方法中定义了其他基本方法的执行步骤,而基本方法的实现可以放在抽象类中,也可以放在其子类中。模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。
定义:定义一个操作中算法的骨架,而将一些不走延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模式结构图:
钩子方法:一个钩子方法由一个抽象类或具体类声明并实现而其子类可能会加以拓展。通常在父类中给出的实现是一个空实现,并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空分默认实现。在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体操作”挂钩“,以确定在不同条件下执行模板方法中不同的不走,这类钩子方法的返回类型通常是boolean类型,这类方法名一般为isXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则某一步骤不执行。还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,钩子方法的好处在于如果没有覆盖父类中定义的钩子方法,编译可以通过,但是如果没有覆盖父类中定义的抽象方法,bian'y将报错。
代码:
客户端:
package com.templatemethodpattern.hing; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub BankTemplateMethod btm = (BankTemplateMethod)XMLUtil.getBean(); btm.process(); } }
抽象类:
package com.templatemethodpattern.hing; public abstract class BankTemplateMethod { public void takeNumber() { System.out.println("取号排队"); } public abstract void transact() ; public void evaluate() { System.out.println("反馈评分!"); } public void process() { takeNumber(); transact(); evaluate(); } }
具体子类:
package com.templatemethodpattern.hing; public class Deposit extends BankTemplateMethod { public void transact() { System.out.println("存款!"); } }
package com.templatemethodpattern.hing; public class Withdraw extends BankTemplateMethod { public void transact() { System.out.println("取款!"); } }
package com.templatemethodpattern.hing; public class Transfer extends BankTemplateMethod { public void transact() { System.out.println("转账!"); } }
总结:模板方法模式在针对一些都有同样的一些步骤的一些情况下使用起来可以大幅减少代码量,将代码的复用技术体现得淋漓尽致。