模板方法模式(Template Method)
一、引言
提到模板,大家肯定不免想到生活中的“简历模板”、“论文模板”、“Word中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下载下来的简历模板的格式都是相同的,然而我们下载下来简历模板之后我们可以根据自己的情况填充不同的内容要完成属于自己的简历。在设计模式中,模板方法模式中模板和生活中模板概念非常类似,下面让我们就详细介绍模板方法的定义,大家可以根据生活中模板的概念来理解模板方法的定义。
二、模板方法模式详细介绍
2.1 模板方法模式的定义
模板方法模式——在一个抽象类中定义一个操作中的算法骨架(对应于生活中的大家下载的模板),而将一些步骤延迟到子类中去实现(对应于我们根据自己的情况向模板填充内容)。模板方法使得子类可以不改变一个算法的结构前提下,重新定义算法的某些特定步骤,模板方法模式把不变行为搬到超类中,从而去除了子类中的重复代码。
2.2 模板方法模式的实现
理解了模板方法的定义之后,自然实现模板方法也不是什么难事了,下面以生活中炒蔬菜为例来实现下模板方法模式。在现实生活中,做蔬菜的步骤都大致相同,如果我们针对每种蔬菜类定义一个烧的方法,这样在每个类中都有很多相同的代码,为了解决这个问题,我们一般的思路肯定是把相同的部分抽象出来到抽象类中去定义,具体子类来实现具体的不同部分,这个思路也正式模板方法的实现精髓所在,具体实现代码如下:
// 客户端调用
class Client
{
static void Main(string[] args)
{
// 创建一个菠菜实例并调用模板方法
Spinach spinach = new Spinach();
spinach.CookVegetabel();
Console.Read();
}
}
public abstract class Vegetabel
{
// 模板方法,不要把模版方法定义为Virtual或abstract方法,避免被子类重写,防止更改流程的执行顺序
public void CookVegetabel()
{
Console.WriteLine("抄蔬菜的一般做法");
this.pourOil();
this.HeatOil();
this.pourVegetable();
this.stir_fry();
}
// 第一步倒油
public void pourOil()
{
Console.WriteLine("倒油");
}
// 把油烧热
public void HeatOil()
{
Console.WriteLine("把油烧热");
}
// 油热了之后倒蔬菜下去,具体哪种蔬菜由子类决定
public abstract void pourVegetable();
// 开发翻炒蔬菜
public void stir_fry()
{
Console.WriteLine("翻炒");
}
}
// 菠菜
public class Spinach : Vegetabel
{ public override void pourVegetable()
{
Console.WriteLine("倒菠菜进锅中");
}
}
// 大白菜
public class ChineseCabbage : Vegetabel
{
public override void pourVegetable()
{
Console.WriteLine("倒大白菜进锅中");
}
}
在上面的实现中,具体子类中重写了导入蔬菜种类的方法,因为这个真是烧菜方法中不同的地方,所以由具体子类去实现它。
2.3 模板方法模式的类图
实现完模板方法模式之后,让我们看看模板方法的类图结构,以理清该模式中类之间的关系,具体类图如下:

模板方法模式中涉及了两个角色:
抽象模板角色(Vegetable扮演这个角色):定义了一个或多个抽象操作,以便让子类实现,这些抽象操作称为基本操作。
具体模板角色(ChineseCabbage和Spinach扮演这个角色):实现父类所定义的一个或多个抽象方法。
三、模板方法模式的优缺点
下面让我们继续分析下模板方法的优缺点。
优点:
实现了代码复用
能够灵活应对子步骤的变化,符合开放-封闭原则
缺点:因为引入了一个抽象类,如果具体实现过多的话,需要用户或开发人员需要花更多的时间去理清类之间的关系。
附:在.NET中模板方法的应用也很多,例如我们在开发自定义的Web控件或WinForm控件时,我们只需要重写某个控件的部分方法。
四、总结
到这里,模板方法的介绍就结束了,模板方法模式在抽象类中定义了算法的实现步骤,将这些步骤的实现延迟到具体子类中去实现,从而使所有子类复用了父类的代码,所以模板方法模式是基于继承的一种实现代码复用的技术。
模板方法模式(Template Method)的更多相关文章
- 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行 ...
- 设计模式 - 模板方法模式(template method pattern) JFrame 具体解释
模板方法模式(template method pattern) JFrame 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(templ ...
- 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)
原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method ...
- 模板方法模式 Template method 行为型 设计模式(二十六)
模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为 ...
- 模板方法模式-Template Method(Java实现)
模板方法模式-Template Method 在模板模式中, 处理的流程被定义在父类中, 而具体的处理则交给了子类. 类关系图很简单: Template接口 这里定义了子类需要实现的方法(before ...
- 设计模式 - 模板方法模式(template method pattern) 排序(sort) 具体解释
模板方法模式(template method pattern) 排序(sort) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(tem ...
- 设计模式 - 模板方法模式(template method pattern) 具体解释
模板方法模式(template method pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 模板方法模式(template metho ...
- 二十四种设计模式:模板方法模式(Template Method Pattern)
模板方法模式(Template Method Pattern) 介绍定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法 ...
- 模板方法模式(Template Method Pattern)——复杂流程步骤的设计
模式概述 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单.吃东西.买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单. 在 ...
- 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)
今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...
随机推荐
- 7月10日——[HouseStark] 扬帆起航--第一次会议
本次会议为小组成员第一次会议 内容:每个成员提出一个及以上的项目及内容,成员内部商议并投票决定要做的项目 会议时长:90分钟 地点:电三楼8楼816室 成员 项目 讨论结果 崔文祥 高校就业信息汇总网 ...
- jQuery初级篇(一)
知识说明: jQuery库是一个javascript库文件,它比起javascript来,写的更少,但做得更多,下面便对刚开始学习jQuery,一些基础知识整理出来,供后期翻阅. 一. jQ ...
- 用JAVA写查询一个字符串中是否包含另外一个字符串以及出现的次数
package JAVA; import java.awt.List;import java.util.ArrayList;/** * * @author 梁小鱼 * */public class ...
- 统计字符串”aaaabbbccccddfgh”中字母个数以及统计最多字母数
function count(){ var str="shhkfahkahsadhadskhdskdha"; var obj={}; for(var i=0;i<str.le ...
- 【笔记】ListView的使用
1.0 ListView三要素 1.0.1 创建基本步骤 1.在布局文件中创建一个ListView组件,并在Activity中声明这个组件. 2.在Activity中,创建一个合适的Adapter. ...
- C++调用V8与JS交互
C++访问JS函数 C++部分: /** * COMPILE foo.js AT THE FIRST COMMAND PROMPT TO RUN foo.js */ #include <v8.h ...
- 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。
用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...
- 微软How old do I Look——初体验
前段时间微软发布了一个可爱的网站how old.net,着实火了一把,全民体验魔镜魅力. 上传自己的靓照到http://www.how-old.net/,它就可以告诉你性别和年龄,大家还习惯称之为“颜 ...
- Rails学习笔记二
rails框架: MVC模型:模型.视图.控制器 来自网站的请求先是被传递到路由,判断请求找出控制器中的方法,处理请求,控制器中的方法也被称作行为 行为可以与模型交互,访问数据库,并为视图准备信息 由 ...
- Redis 常用链接
安装部署 http://www.linuxidc.com/Linux/2014-05/101979.htm 更改访问权限配置(如密码,可访问地址):http://www.jb51.net/articl ...