1、核心
定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。
2、应用场景
—数据库访问的封装
—Junit单元测试
—servlet中关于doGet/doPost方法调用
—Hibernate中模板程序
—spring中JDBCTemplate、HibernateTemplate等
3、模板方法模式角色
—抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
—具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
4、代码示例
问题:银行办理业务,流程固定(取号–>办理业务–>反馈评分),只是办理业务步骤不同。
/**
* 银行业务模板
* @author ly1
*
*/
public abstract class BankTemplate {
/**
* 固定流程:取号-->办理业务-->反馈评分
*/
public final void process(){
takeNumber();
transaction();
evaluate();
}
/**
* 取号
*/
public void takeNumber(){
System.out.println("取号");
}
/**
* 办理业务,子类实现
*/
public abstract void transaction();
public void evaluate(){
System.out.println("反馈评分!");
}
}
/**
* 取钱业务
* @author ly1
*
*/
public class WithdramMoney extends BankTemplate{
@Override
public void transaction() {
System.out.println("取款");
}
}
/**
* 存款业务
* @author ly1
*
*/
public class Deposit extends BankTemplate{
@Override
public void transaction() {
System.out.println("存款");
}
}
/**
* 客户端调用
* @author ly1
*
*/
public class Client {
public static void main(String[] args) {
BankTemplate bt1 = new WithdramMoney();
bt1.process();
BankTemplate bt2 = new Deposit();
bt2.process();
//也可以创建匿名内部类
BankTemplate bt3 = new BankTemplate() {
@Override
public void transaction() {
System.out.println("开通网银");
}
};
bt3.process();
}
}
结果:
取号
取款
反馈评分!
取号
存款
反馈评分!
取号
开通网银
反馈评分!
5、优点
- 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
- 子类实现算法的某些细节,有助于算法的扩展。
- 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
6、缺点
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。