十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
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.定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改
变一个算法的结构即可重定义该算法的某些特定步骤。创新互联服务项目包括东明网站建设、东明网站制作、东明网页制作以及东明网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,东明网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到东明省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
模板方法模式非常简单,主要是用了Java的继承机制,话不多说,直接上代码
public abstract class AbstractClass { /** * 基本方法 */ protected abstract void doSomething(); /** * 基本方法,可以有默认实现 */ protected void doAnything() { System.out.println("AbstractClass doAnything()"); } /** * 模板方法,为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写 */ public final void templateMethod(){ doSomething(); doAnything(); } }
public class ConcreteClassA extends AbstractClass { @Override protected void doSomething() { System.out.println("ConcreteClassA doSomething()"); } @Override protected void doAnything() { System.out.println("ConcreteClassA doAnything()->我不想使用父类的默认实现,我要覆盖它"); } }
public class ConcreteClassB extends AbstractClass { @Override protected void doSomething() { System.out.println("ConcreteClassB doSomething()"); } // 使用父类doAnything()的默认实现}
public class Client { public static void main(String[] args) { AbstractClass a = new ConcreteClassA(); a.templateMethod(); AbstractClass b = new ConcreteClassB(); b.templateMethod(); } }
按照我们的设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成
具体的事物属性和方法。但是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类
实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目
中,会带来代码阅读的难度,而且也会让新手产生不适感。
子类实现。
过 钩子 函数(详见后面的扩展示例)约束其行为。
模板方法模式的扩展,主要就是增加了钩子方法(Hook Method),那么什么是“钩子方法”呢?
在抽象模板类中,可以定义一个方法,并允许子类视情况覆盖它来改变基本方法的执行过程(比如决定某些步骤是否需要执行)
钩子方法的作用
下面是增加钩子方法后的模板方法模式通用代码:
public abstract class AbstractClass { /** * 基本方法 */ protected abstract void doSomething(); /** * 基本方法 */ protected void doAnything() { System.out.println("AbstractClass doAnything()"); } /** * 依赖于钩子方法的基本方法 */ protected abstract void dependOnHook(); /** * 模板方法,为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写 */ public final void templateMethod(){ doSomething(); doAnything(); if (hook()){ dependOnHook(); } } /** * 钩子方法:空实现或默认实现,子类可以覆写;由子类的一个方法返回值决定公共部分的执行结果 * @return */ protected boolean hook(){ System.out.println("AbstractClass hook()"); return true; } }
public class ConcreteClassA extends AbstractClass { @Override protected void doSomething() { System.out.println("ConcreteClassA doSomething()"); } @Override protected void doAnything() { System.out.println("ConcreteClassA doAnything()->我不想使用父类的默认实现,我要覆盖它"); } @Override protected void dependOnHook() { System.out.println("ConcreteClassA dependOnHook()"); } // 没有覆写钩子方法,使用默认实现,dependOnHook()将会被调用}
public class ConcreteClassB extends AbstractClass { @Override protected void doSomething() { System.out.println("ConcreteClassB doSomething()"); } // 使用父类doAnything()的默认实现 @Override protected void dependOnHook() { System.out.println("ConcreteClassB dependOnHook()"); } /** * 覆写钩子方法,改变默认实现,改变公共部分(模板方法)的行为,dependOnHook()不会被调用 * @return */ @Override protected boolean hook(){ System.out.println("ConcreteClassB hook()"); return false; } }
源码地址: https://gitee.com/tianranll/java-design-patterns.git
参考文献《设计模式之禅》