《程序猿之设计模式实战 · 模板方法》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍
文章目录
- 写在前面的话
- 基础介绍
- 代码实现
- Spring 中的模板方法
- Servlet中的模板方法
- 扩展补充
- 总结陈词
写在前面的话
本篇文章继续介绍一下观察者模式,这个在日常工作中接触还是挺多的,但和发布订阅模式又有什么不同呢?
相关文章:
《程序猿之设计模式实战 · 策略模式》
《程序猿之设计模式实战 · 装饰者模式》
《程序猿之设计模式实战 · 池化思想》
《程序猿之设计模式实战 · 观察者模式》
《程序猿之设计模式实战 · 责任链模式》
基础介绍
基础概念:
1、模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。
2、模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
Tips:看起来是否好像就是 Java 抽象类的用法呢?
模板方法的结构:
模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术。模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法;而将这些基本方法汇总起来的方法叫做模板方法,这个设计模式的名字就是从此而来。
主要组成部分:
1、抽象类:定义了一个模板方法,包含算法的骨架。定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
2、具体类:实现了抽象类中定义的某些步骤。实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
使用场景:
- 当你有一个算法的多个变体时,可以使用模板方法模式来避免重复代码。
- 当你希望控制子类扩展的步骤,但不希望改变算法的整体结构时。
- 在框架设计中,提供一个可扩展的基础结构。
代码实现
// 抽象类
abstract class AbstractClass {
// 模板方法
public final void templateMethod() {
stepOne();
stepTwo();
stepThree();
}
protected abstract void stepOne();
protected abstract void stepTwo();
// 具体实现
private void stepThree() {
System.out.println("Step Three: Common Implementation");
}
}
// 具体类A
class ConcreteClassA extends AbstractClass {
@Override
protected void stepOne() {
System.out.println("ConcreteClassA: Step One Implementation");
}
@Override
protected void stepTwo() {
System.out.println("ConcreteClassA: Step Two Implementation");
}
}
// 具体类B
class ConcreteClassB extends AbstractClass {
@Override
protected void stepOne() {
System.out.println("ConcreteClassB: Step One Implementation");
}
@Override
protected void stepTwo() {
System.out.println("ConcreteClassB: Step Two Implementation");
}
}
// 测试
public class TemplateMethodDemo {
public static void main(String[] args) {
AbstractClass classA = new ConcreteClassA();
classA.templateMethod();
System.out.println();
AbstractClass classB = new ConcreteClassB();
classB.templateMethod();
}
}
Spring 中的模板方法
在 Spring 框架中,模板方法模式被广泛应用于各种组件中,尤其是在数据访问和事务管理方面。以下是一些常见的应用场景:
1、JdbcTemplate:Spring 提供的 JdbcTemplate 类使用模板方法模式来简化 JDBC 操作。用户只需实现特定的回调方法,而不需要关心底层的 JDBC 细节。
2、事务管理:Spring 的事务管理也使用了模板方法模式,允许用户定义事务的边界,而具体的事务处理逻辑则由 Spring 处理。
3、RestTemplate:在进行 RESTful 服务调用时,RestTemplate 提供了一系列的模板方法,用户只需关注请求的具体细节。
总结:模板方法设计模式通过定义算法的骨架,使得子类可以灵活地实现特定的步骤。这种模式在 Spring 框架中得到了广泛应用,极大地简化了开发过程,提高了代码的可复用性和可维护性。
Servlet中的模板方法
使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类。HttpService类提供了一个service()方法,这个方法调用七个do方法中的一个或几个,完成对客户端调用的响应。这些do方法需要由HttpServlet的具体子类提供,因此这是典型的模板方法模式。
扩展补充
看上面的介绍,模板方法好像就是Java抽象类的基础用法,公用部分的代码写在抽象类,特殊的子类自己定义,这有什么特殊之处吗?
其实两者还是有一些区别:
- 算法的骨架与步骤的分离
模板方法模式明确区分了算法的整体结构(骨架)和具体实现(步骤)。这使得算法的变化和扩展变得更加灵活。子类只需关注特定步骤的实现,而不需要重新实现整个算法。
- 控制扩展
模板方法模式允许父类控制算法的执行流程,确保子类只能在特定的步骤中进行扩展。这种控制机制有助于维护算法的一致性和完整性。
- 代码复用
通过将公共逻辑放在抽象类中,模板方法模式促进了代码的复用。多个子类可以共享相同的逻辑,减少了代码重复。
- 易于维护
由于算法的结构在父类中定义,任何对算法结构的修改只需在父类中进行,而不需要在每个子类中重复修改。这提高了代码的可维护性。
- 适应性
模板方法模式可以很容易地适应变化。例如,如果需要在算法中添加新的步骤,只需在抽象类中添加方法,并在子类中实现即可。
- 与钩子方法结合使用
模板方法模式通常与钩子方法结合使用。钩子方法是一些可以被子类选择性重写的方法,允许子类在不改变算法结构的情况下插入自定义行为。
总结陈词
介绍了这么多,其实模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术。也不用过多纠结它和抽象方法的区别是什么,在日常中学会使用这种抽象或模板封装思维,才是最重要的。遇到实际问题能使用合适的方式解决,同时代码经得起推敲和扩展,才是最主要的。
还是那句话,你可以不用,但不能不会。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。