Template Method
概念
模板方法:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure. 在一个操作中定义一个算法骨架,并将某些步骤推迟到子类实现。可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。
模板方法的作用:
复用:子类都可以复用父类中模板方法定义的流程代码。如 InputStream、OutputStream、Reader、Writer,AbstractList 等。
扩展:更多指框架的扩展性,类似控制反转,可以让用户不修改框架源码的情况下,定制化框架的功能。如 Java Servlet、JUnit 等。
示例
public abstract class AbstractClass {
public final void templateMethod() {
//...
method1();
//...
method2();
//...
}
protected abstract void method1();
protected abstract void method2();
}
public class ConcreteClass extends AbstractClass {
@Override
protected void method1() {}
@Override
protected void method2() {}
}
AbstractClass demo = ConcreteClass();
demo.templateMethod();源码
InputStream
AbstractList
Servlet
用户实现的扩展点:
Servlet 容器收到请求后,会找到相应的 Servlet,并调用它的 service 方法。框架的模板方法:
JUnit
JUnit 提供了一些扩展点,如 setUp(), tearDown() 等。
Callback
回调与模板模式一样也具有复用和扩展的功能。
原理
A 类事先注册某个函数 F 到 B 类,A 类在调用 B 类的 P 函数时,B 类反过来调用 A 类注册给 B 类的 F 函数,F 就叫做回调函数。
回调有同步回调和异步回调,同步回调更像模板模式,异步回调更像观察者模式。
示例
JdbcTemplate
Spring 提供很多 Template 类,但它们并非基于模板方法实现,而是基于 Callback 实现。
如果直接写 JDBC 代码会很冗余,比如:
加载驱动、创建连接、关闭连接等很多操作与业务无关,这些流程大多可以复用,所以 Spring 提供了 JdbcTemplate,用户代码可以变得非常简洁:
JdbcTemplate 核心的逻辑如下:
Hook
Callback 更加注重语法机制的描述,Hook 更加侧重应用的描述。Tomcat 和 JVM 都有shutdown hook,以 JVM 为例,当应用程序关闭时,会调用 ApplicationShutdownHooks 的 runHooks 方法:
比较
同步回调几乎与模板模式一致,都是在一个大的算法骨架中,自由替换其中的个别步骤,起到代码复用和扩展的目的。
实现方式:模板方法基于继承;回调基于组合。
组合优于继承,那么回调相对于模板方法的优势如下:
Java 只支持单继承。
回调可以使用匿名类,不用事先定义类。
如果一个类有多个模板方法,每个类都有对应的抽象方法,那么模板方法需要实现所有的抽象方法;而回调只需要往我们需要的模板方法中注入回调对象即可。
Last updated
Was this helpful?
