java常用设计模式之模板方法模式
1、模板方法定义
模板方法模式属于行为型模式,它定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
2、模板方法结构
2.1、抽象模板类(Abstract Class)
抽象模板类,负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
1、模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法;
2、基本方法:是整个算法中的一个步骤,包含以下几种类型:
抽象方法:在抽象类中声明,由具体子类实现;
具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它;
钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
2.2、具体实现子类(Concrete Class)
具体实现类,实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。
模板方法模式的结构图如图:
3、模板方法模式DEMO
1 |
|
4、模板方法模式优缺点及使用场景
优点
a.它封装了不变部分,扩展可变部分。它把不变部分封装到父类中实现,而把可变部分由子类继承实现,便于子类继续扩展。
b.它在父类中提取了公共的部分代码,便于代码复用。
c.部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
缺点
a.对每个不同的实现都需要定义一个子类,这会导致类的个数增加,间接地增加了系统实现的复杂度。
b.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,提高了代码阅读的难度。
c.由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。
使用场景
a.针对整体步骤固定,其中个别部分易变的,可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
b.当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。
举个例子:
集合中的AbstractList是很多集合类的父类,会把一些公共部分放在抽象父类中,一些可扩展的方法让子类实现;
JUC中的AQS,提供了一套同步控制器的模板,通过这一套模板实现了ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore等功能;
Spring中的各种Template,如RestTemplate, JdbcTemplate, RedisTemplate, RabbitTemplate等都使用了模板方法模式;
Tomcat中生命周期设计,LifecycleBase实现了init、start、stop、destroy等生命周期的方法,也是模板方法,也留了一些抽象方法 initInternal、startInternal、stopInternal、destoryInternal给子类去实现;
MyBatis中的执行器,如BaseExecutor。
模板方法模式重要的2点:代码复用和功能扩展,如果不想让子类实现,可以提供默认空实现或者抛异常。