今天,我们来学习行为型设计模式中的第二个:模板模式。
模板模式主要是用来解决复用和扩展 两个问题。
话不多说,开始今天的学习。
介绍
模板模式(Template Method Design Pattern): 模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。
这里的算法骨架就是“模板”,通用的代码实现很简单。
原理与实现
AbstracTemplate.java
1 | java复制代码public abstract class AbstracTemplate { |
ConcreteClassA.java、ConcreteClassB.java
1 | java复制代码public class ConcreteClassA extends AbstracTemplate { |
Test.java
1 | java复制代码public class Test { |
结果:
作用一:复用
模板模式的作用之一:复用
模板模式把一个算法中不变的流程抽象到父类的模板方法 templateMethod()中,将可变的部分 methodA()、methodB() 留给子类 ConcreteClassA 和 ConcreteClassB 来实现。所有的子类都可以复用父类中模板方法定义的流程代码。
Java AbstractList
在 Java AbstractList 类中,addAll() 函数可以看作模板方法,add() 是子类需要重写的方法,尽管没有声明为 abstract 的,但函数实现直接抛出了 UnsupportedOperationException 异常。前提是,如果子类不重写是不能使用的。
1 | java复制代码public boolean addAll(int index, Collection<? extends E> c) { |
还有在Java IO 类库汇总,有很多的类的设计也用到了模板模式,比如 InputStream、OutputStream、Reader、Writer。
作用二:扩展
模板模式的作用之二:扩展。
基于这个作用,模板模式常用在框架的开发中,让框架用户可以在不修改框架源码的情况下,定制化框架的功能。
还记得当初学 Java Web 开发时,必然会学到 Servlet。使用 Servlet 来开发 Web 项目时,我们需要定义一个继承 HttpServlet 的类,并且重写其中的 doGet() 或 doPost() 方法,来分别处理 get 和 post 请求。具体代码示例如下所示:
1 | java复制代码public class TestServlet extends HttpServlet { |
当请求到这个 Servlet 的时候会执行 它的 service() 方法。service() 方法定义在父类 HttpServlet 中,它会调用 doGet() 或 doPost() 方法,然后输出数据 “Hello world” 到网页。
1 | java复制代码protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
可以看到,service() 方法就是一个模板方法,它实现了整个 HTTP 请求的执行流程,doGet()、doPost() 是模板中可以由子类来定制的部分。实际上,这就相当于 Servlet 框架提供了一个扩展点(doGet()、doPost() 方法),让框架用户在不用修改 Servlet 框架源码的情况下,将业务代码通过扩展点镶嵌到框架中执行。
总结
模板模式的优点:
- 具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法整体结构。
- 代码复用的基本技术,在数据库设计中尤为重要。
- 存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则”。
本文转载自: 掘金