模板方法模式 Template method
上图为网上百度的一份简历模板截图
 
相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的内容。 
 
我们从小就有语文课,逢考必有作文,而学习的途径之一就是参考优秀的范文,学习了解他们的结构,风格等。
以上就是现实世界中的模板,模板的概念随处可见,所有的工业制品哪个不是模具生产的?
 
在程序设计中,也有模板的概念
在软件开发过程中,可能经常会用到类似的处理逻辑,但是可能又有一些细节的差异
比如做菜,不管做什么菜,基本上都离不开买菜,洗菜,切菜,做菜几个主要步骤
这几个步骤中,只有做菜的差别最大,不同的菜不同的做法,而买菜洗菜切菜的过程,却基本类似
 
我们常常希望能够定义一个通用的处理框架,然后将一部分实现细节交由子类进行处理
也就是面向框架进行编程,而不是每次都复制粘贴修改代码,具体的细节依靠子类确定,这就是模板的初衷。 
 
比如定义一个做菜的抽象类,实现了买菜,洗菜,切菜,做菜方法定义为抽象方法留待子类实现
那么,回锅肉和大头菜就可以通过继承扩展做菜类,只需要实现做菜的环节即可。

意图

定义一个操作中的算法的骨架,而将一些步骤延时到子类中。
TemplateMethod使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤。

结构

 
抽象模板角色AbstractClass
定义一个或者多个抽象步骤,这些抽象操作叫做基本操作
他们可能是一个复杂操作的组成步骤
实现类角色ConcreteClass
实现父类所定义的一个或者多个抽象方法
 
每一个抽象模板都可以有任意多个具体的模板角色与之对应,而实际中,一般不止一个

代码示例

定义做菜步骤:买菜,洗菜,切菜,做菜。
买菜、洗菜、切菜都一样,做菜不同菜不同做法
上菜将他们步骤进行打包
package template;

public abstract class 做菜 {
public void 买菜(){
System.out.println("买菜...");
}
public void 洗菜(){
System.out.println("洗菜...");
}
public void 切菜(){
System.out.println("切菜...");
}
public abstract void 做菜(); public void 上菜(){
买菜();
洗菜();
切菜();
做菜();
System.out.println("客官,菜来了~~~");
}
}
做回锅肉和做大头菜都重写了“做菜”的方法
package template;

public class 做回锅肉 extends 做菜 {
@Override
public void 做菜() {
System.out.println("做回锅肉...");
}
}
package template;
public class 做大头菜 extends 做菜 {
@Override
public void 做菜() {
System.out.println("做大头菜...");
}
}

测试代码

方法分类

通常模板模式中会涉及到两类方法,模板方法和基本方法
模板方法指的是定义在抽象类中,把基本方法组合在一起形成复杂逻辑的方法,通常子类是不修改这个方法的
模板方法给出来顶层的逻辑框架。
比如上面的“上菜”,上菜方法调用了“买菜,洗菜,切菜,做菜”
可以有任意多个的模板方法
 
另一类就是基本方法了,基本方法就是复杂方法的组成部分
基本方法又有几种形式
抽象方法,具体方法,钩子方法
抽象方法:abstract定义,子类实现
具体方法:抽象类具体实现
钩子方法:抽象类提供默认实现的方法,经常是一个空实现,好处是子类不是必须实现
 
前面说到,模板方法定义了顶层的框架逻辑,而且子类一般不修改,直接继承。

可以通过钩子方法对顶层框架逻辑进行微调

比如上面做菜的示例中,上菜的环节中,新增加一个方法用来判断是否需要切菜
 
做大头菜类中,重写这个方法,做大头菜,不切了
 
再来看看打印结果,大头菜,没切就做了。。。。。

总结

模板方法模式的根本在于共性的提取与解题步骤框架化
通常使用继承机制完成这一目标
 
继承使得类型的等级结构易于理解,层次分明,非常适合抽象化的设计
但是继承随之而来的强耦合,也将会导致很多的不便,比如打破了封装,父类向子类暴露
不能在运行时动态更改,父类改变,子类很可能也需要改变
所以继承是一把双刃剑,使用不当也会导致很大的问题。
但是,不能因噎废食,个人认为对继承的态度应该是不滥用,不弃用
 
模板模式也可以用于方法层次上方法的拆解,如果一个方法中有很多的代码逻辑步骤
那么,可以借助于模板模式定义解题步骤,将步骤进行拆解
比如原方法为
step()
拆分后为
step(){
  step1();
  step2();
  ....
}
原来的step的方法就相当于抽象类,step1,step2就相当于具体的子类
 
模板模式的根本就是共性的提取以及解题步骤框架化(就是步骤分明处理)
所以千万不要认为模板就仅仅只是继承,实现接口就表示模板的概念了么?个人认为仍旧是
没有模板方法,仅仅是基本方法就不是模板模式了么?个人认为仍旧是
模板方法仍旧是依赖倒置原则的实现方案。
只不过模板模式相对于面向抽象编程,又进一步期望父类提供更多给子类,比如算法逻辑框架
将部分职责延迟到子类。
 
借助于钩子方法的形式,可以引入更多的灵活性,子类可以对父类的整体逻辑做出微调
达到了反向控制的效果---子类控制了父类方法的细节步骤
 
涉及到共性提取或者框架步骤分割的都可以考虑模板模式
 

模板方法模式 Template method 行为型 设计模式(二十六)的更多相关文章

  1. 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)

      设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行 ...

  2. 二十四种设计模式:模板方法模式(Template Method Pattern)

    模板方法模式(Template Method Pattern) 介绍定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法 ...

  3. 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)

    原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method ...

  4. 设计模式 - 模板方法模式(template method pattern) JFrame 具体解释

    模板方法模式(template method pattern) JFrame 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(templ ...

  5. 设计模式 - 模板方法模式(template method pattern) 排序(sort) 具体解释

    模板方法模式(template method pattern) 排序(sort) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(tem ...

  6. 设计模式 - 模板方法模式(template method pattern) 具体解释

    模板方法模式(template method pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 模板方法模式(template metho ...

  7. 模板方法模式(Template Method Pattern)——复杂流程步骤的设计

    模式概述 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单.吃东西.买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单. 在 ...

  8. 模板方法模式-Template Method(Java实现)

    模板方法模式-Template Method 在模板模式中, 处理的流程被定义在父类中, 而具体的处理则交给了子类. 类关系图很简单: Template接口 这里定义了子类需要实现的方法(before ...

  9. 【设计模式】行为型02模板方法模式(Template Method Patten)

    五一长假,没有出去,不喜欢嘈杂的人群,玩了会游戏发泄了下憋在心底的戾气,手旁大马克杯里是母亲泡的绿茶.点开自己的播放列表,耳机里传来的是理查德克莱德曼的致爱丽丝.自己是个凡人,卑微渺小的活着.不说废话 ...

随机推荐

  1. Python并发编程之线程中的信息隔离(五)

    大家好,并发编程 进入第三篇. 上班第一天,大家应该比较忙吧.小明也是呢,所以今天的内容也很少.只要几分钟就能学完. 昨天我们说,线程与线程之间要通过消息通信来控制程序的执行. 讲完了消息通信,今天就 ...

  2. Thymeleaf中each标签遍历list如何获取index

    <tr th:each="user,userStat:${users}">userStat是状态变量,有 index,count,size,current,even,o ...

  3. codeforces 983B XOR-pyramid

    题意: 定义一个函数f(a): 给出一个数组a,有q个询问,每次询问回答在l到r的区间内,连续子串的f函数的最大值. 思路: 画图,来自codeforces SheepRanger 由此图可知,f(l ...

  4. System.nanoTime理解

    JDK1.5之后java中的计时给出了更精确的方法:System.nanoTime(),输出的精度是纳秒级别,这个给一些性能测试提供了更准确的参考. 但是这个方法有个需要注意的地方,不能用来计算今天是 ...

  5. HTML和CSS前端基础

    Html标题 <h1>这是一级标题</h1> <h2>这是二级标题</h2> <h3>这是三级标题</h3> Html段落.换行 ...

  6. Day1 《机器学习》第一章学习笔记

    <机器学习>这本书算是很好的一本了解机器学习知识的一本入门书籍吧,是南京大学周志华老师所著的鸿篇大作,很早就听闻周老师大名了,算是国内机器学习领域少数的大牛了吧,刚好研究生做这个方向相关的 ...

  7. npm install 遇到问题的解决

    在利用npm install 命令时,要以管理员权限运行CMD,然后进入到npm-modules目录,然后再执行install命令

  8. GraphicsMagick+im4java实现高质量大图的处理

    http://www.open-open.com/lib/view/open1355754261963.html 做网站往往需要处理各种各样的图片,对于jdk自带的一套图片处理库,他的特点是稳定简单, ...

  9. CFile类的open方法中的参数说明

    CFile::Open是在MFC里面,打开一个文件的方法. Open函数的原型如下: virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, ...

  10. bzoj 4916: 神犇和蒟蒻 (杜教筛+莫比乌斯反演)

    题目大意: 读入n. 第一行输出“1”(不带引号). 第二行输出$\sum_{i=1}^n i\phi(i)$. 题解: 所以说那个$\sum\mu$是在开玩笑么=.= 设$f(n)=n\phi(n) ...