模板方法模式 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 + Appium 环境搭建

    ---恢复内容开始--- Appium自动化公司内部测试培训1-环境搭建 课程目的 一.Python + Appium 环境搭建 课程内容 1    安装前准备工作 搭建环境所需要的安装文件已经下载好 ...

  2. OpenStack架构详解

    OpenStack提供开放源码软件,建立公共和私有云. OpenStack是一个社区和一个项目,以及开放源码软件,以帮助企业运行的虚拟计算或者存储云. OpenStackd开源项目由社区维护,包括Op ...

  3. 消息中间件activemq的使用场景介绍(结合springboot的示例)

    一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题.实现高性能,高可用,可伸缩和最终一致性架构.是大型分布式系统不可缺少的中间件. 目前在生产环境,使 ...

  4. 自动化运维工具sshd,expect,pssh,rsync详解

    ssh secure shell,安全的远程登录:openssh和dropbear都是它的开源实现,ssh协议有v1和v2俩个版本,现在使用的都是v2版,v1已经不安全了:ssh基于DH算法做密钥交换 ...

  5. jennifersoft,phantomjs

    http://jennifersoft.com/en/ Real Value of APM (Application Performance Monitoring) http://npm.taobao ...

  6. 关于table相关的属性,CSS样式

    table属性: 1:border没有设置的话表格没有边框 2:cellpadding单元格和内容的空白 3:cellspacing单元格和单元格之间的空白 4:frame规定外边框可见性 5:rul ...

  7. 底层网络技术以及IP编址

    网络信息的传输在最底层总是依托于物理介质来进行传输的,这里的传输介质分为两种: 有线介质  导线管(导向媒体).例如:双绞线.同轴电缆.光纤等 无线介质  电磁波(非导向媒体):利用各种波长的电磁波充 ...

  8. HTTP/HTTPS 学习笔记

    超文本传输协议(HyperText Transfer Protocol) 伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是建立在TCP协议之上的. HTT ...

  9. Tomcat 优化方案 和 配置详解(转)

    转自 Tomcat 优化方案 和 配置详解 http://201605130349.iteye.com/blog/2298985 Server.xml配置文件用于对整个容器进行相关的配置. <S ...

  10. 在MFC中怎么获得Excel文档中已经使用了的行数和列数

    _Worksheet ws;Range range; range = ws.GetUsedRange();//获得Worksheet已使用的范围range = range.GetRows();   / ...