定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的重复代码全部在父类里面,不同业务的,抽取给子类进行实现。
模板方法模式
核心:说白了,就是将一些相同操作的代码,封装成一个算法的骨架。核心的部分留在子类中操作,在父类中只把那些骨架做好。
例如:
- 去银行办业务,银行给我们提供了一个模板就是:先取号,排对,办理业务(核心部分我们子类完成),给客服人员评分,完毕。这里办理业务是属于子类来完成的,其他的取号,排队,评分则是一个模板。
- 去餐厅吃饭,餐厅给提供的一套模板就是:先点餐,等待,吃饭(核心部分我们子类完成),买单
这里吃饭是属于子类来完成的,其他的点餐,买单则是餐厅提供给我们客户的一个模板。
什么时候使用模板方法
实现一些操作时,整体步骤很固定,但是呢。就是其中一小部分容易变,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
UML类图
✍举个简单的例子:(银行排队办理业务)
创建抽象类 一些公共方法的封装 留出一个抽象方法由不同的子类实现来实现不同的业务
public abstract class BankTemplateMethod {
// 1.取号排队
public void takeNumber() {
System.out.println("取号排队..");
}
// 2.每个子类不同的业务实现,由各自子类实现.
abstract void transact();
// 3.评价
public void evaluate() {
System.out.println("反馈评价..");
}
public void process(){
takeNumber();
transact();
evaluate();
}
}
不同方法由子类需求实现
public class GetMoney extends BankTemplateMethod {
void transact() {
System.out.println("我需要取钱");
}
}
public class PutMoney extends BankTemplateMethod {
@Override
void transact() {
System.out.println("我需要存钱");
}
}
// 测试类
public class ClientTest {
public static void main(String[] args) {
BankTemplateMethod getMoney = new GetMoney();
getMoney.process();
System.out.println("------------------");
BankTemplateMethod putMoney = new PutMoney();
putMoney.process();
}
}
✨运行结果:
给人感觉像什么呢?是不是有点像Spring框架里面的AOP实现的效果????~ 但是不是说AOP就是这样实现的啊!????我只是想说这个样子很像!
优缺点
-
提高代码复用性
将相同部分的代码放在抽象的父类中 -
提高了拓展性
将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为 -
实现了反向控制
通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合“开闭原则” -
引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。
应用场景
其实,各个框架中,都有模板方法模式的影子。
数据库访问的封装、Junit单元测试、servlet中关于doGet/doPost方法的调用Hibernate中模板程序、spring中JDBCTemplate,HibernateTemplate等等.
总结
模板方法模式应该是最简单的一个模式,也是我们在基础的开发中经常遇到或者用到的模式.总的来说呢模板方法模式就是对一些公共方法进行了一些封装.这个思想应该很容易理解.