设计模式
一、模板方法的概述
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类则在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
二、解决的问题
- 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,由子类来实现。
- 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变(或未知),易变部分可以抽象出来,供不同子类实现。这就是一种模板方法。
三、代码实例
如下所示,
- 一个"银行Bank"的业务流程是固定不变的,即"抽号—>办理业务—>评分",
- 其中抽号、评分操作是已经实现的,
- 但是办理业务是未知的(现在还不能确定办理什么业务,不同业务的操作不同),因此必须设置为抽象的,由子类来具体实现
- 子类只需实现process()方法,明确业务操作即可
【就像"英语作文模板"一样,即,整体框架搭好(“模板”),然后把空缺部分填上自己的内容(实现抽象方法)】
/*
* 抽象类的应用:模板方法的设计模式
*/
public class TemplateTest {
public static void main(String[] args) {
BankTemplateMethod b1 = new DrawMoney();
b1.process();
BankTemplateMethod b2 = new ManageMoney();
b2.process();
}
}
abstract class BankTemplateMethod{
//具体方法
public void takeNumber(){
System.out.println("排队取号");
}
public abstract void transact(); //办理业务的具体方法(钩子方法/回调方法)
public void evaluate(){
System.out.println("反馈评分");
}
//模板方法,把基本操作组合在一起【业务流程是固定的(模板),只是具体执行什么业务是未知的,要交由子类实现】
public final void process(){
takeNumber();
transact(); //像个钩子,具体执行时,勾住哪个子类,就执行哪个子类的实现代码
evaluate();
}
}
class DrawMoney extends BankTemplateMethod{
@Override
public void transact() {
System.out.println("我要取钱!!!!!!");
}
}
class ManageMoney extends BankTemplateMethod{
@Override
public void transact() {
System.out.println("我要理财!!!!!!");
}
}
四、应用场景
- 数据库访问封装
- JUnit单元测试
- JavaWeb的Servlet中关于doGet/doPost方法调用
- Hibernate中模板程序
- Spring中JDBCTemplate、Hibernate Template等