标签 : Java与设计模式
模板方法模式: 定义一个操作中的算法的骨架, 而将一些步骤延迟到子类中. 模板方法使得子类可以在不改变一个算法的结构的前提下重定义该算法的某些特定步骤.
Tips
处理某个流程的骨架代码已经具备, 但其中某节点的具体实现暂不确定, 此时可采用模板方法, 将该节点的代码实现转移给子类完成. 即: 处理步骤在父类中定义好, 具体实现延迟到子类中定义.
到ATM取款机办理业务, 都会经过插卡、输密码、处理业务、取卡 等几个过程, 而且这几个过程一定是顺序执行的, 且除了 处理业务 (如取款、改密、查账) 可能会有所不同之外, 其他的过程完全相同. 因此我们就可以参考模板方法模式把插卡、输密码、取卡 3个过程放到父类中实现, 并定义一个流程骨架, 然后将 处理业务的具体逻辑 放到子类中:
AbstractClass 抽象模板:
定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各步骤.
实现一个模板方法,定义一个算法的骨架. 该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作.
<code>AbstractATMBusiness</code>是一个模板方法, 它定义了ATM操作的一个主要步骤并确定他们的先后顺序, 但允许子类改变这些具体步骤以满足各自的需求.
ConcreteClass
实现原语操作以完成算法中与特定子类相关的步骤; 每个AbstractClass都可有任意多个ConcreteClass, 而每个ConcreteClass都可以给出这些抽象方法的不同实现, 从而使得顶级逻辑的功能各不相同:
Client
<code>HttpServlet</code>定义了<code>service()</code>方法固定下来HTTP请求的整体处理流程,使得开发Servlet只需继承<code>HttpServlet</code>并实现<code>doGet()</code>/<code>doPost()</code>等方法完成业务逻辑处理, 并不需要关心具体的HTTP响应流程:
将这个示例放在此处可能有些不大合适, 但它也体现了一些模板方法的思想:
ScheduleTaskMonitor
ScheduleTask
只需在Spring的配置文件中引入该Bean:
需要统一定时的类实现<code>ScheduleTask</code>接口, 并将自己注册到<code>monitor</code>中:
即可完成<code>scheduleTask()</code>方法的定时调度.
模板方法模式提供了一个很好的代码复用平台, 他通过把不变行为搬移到父类, 去除子类中重复代码来体现它的优势: 有时我们会遇到由一系列步骤构成的过程需要执行, 该过程从高层次上看是相同的, 但有某些细节的实现可能不同, 此时就可以考虑使用用模板方法了.
适用
一次性实现算法的不变部分, 并将可变的行为留给子类来实现;
各子类中公共的行为应该被提取出来并集中到一个公共父类中避免代码重复, 如: Servlet 的 <code>service()</code>方法.
控制子类扩展, 模板方法只在特定点调用hook操作, 这样就只允许在这些点进行扩展, 如: Junit测试框架.
相关模式
Factory Method常被模板方法调用.
Strategy: 模板方法使用继承来改变算法的一部分, Strategy使用委托来改变整个算法.
<dl></dl>
<dt>参考 & 扩展</dt>