一、引言

  提到模板,大家肯定不免想到生活中的“简历模板”、“论文模板”、“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 模板方法模式的类图

  实现完模板方法模式之后,让我们看看模板方法的类图结构,以理清该模式中类之间的关系,具体类图如下:

  

  模板方法模式中涉及了两个角色:

  1)抽象模板角色(Vegetable扮演这个角色):定义了一个或多个抽象操作,以便让子类实现,这些抽象操作称为基本操作。

  2)具体模板角色(ChineseCabbage和Spinach扮演这个角色):实现父类所定义的一个或多个抽象方法。

  三、模板方法模式的优缺点

  下面让我们继续分析下模板方法的优缺点。

  优点:

  1)实现了代码复用;

  2)能够灵活应对子步骤的变化,符合开放-封闭原则;

  缺点:

  1)因为引入了一个抽象类,如果具体实现过多的话,需要用户或开发人员需要花更多的时间去理清类之间的关系。

  附:在.NET中模板方法的应用也很多,例如我们在开发自定义的Web控件或WinForm控件时,我们只需要重写某个控件的部分方法。

  四、总结

  到这里,模板方法的介绍就结束了。模板方法模式在抽象类中定义了算法的实现步骤,将这些步骤的实现延迟到具体子类中去实现,从而使所有子类复用了父类的代码。所以模板方法模式是基于继承的一种实现代码复用的技术。

参考链接:http://www.cnblogs.com/zhili/p/TemplateMethodPattern.html

【15】模板方法模式(Template Method)的更多相关文章

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

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

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

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

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

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

  4. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图   相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为 ...

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

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

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

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

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

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

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

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

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

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

  10. 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)

    今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...

随机推荐

  1. java servlet编写验证码

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.Buffere ...

  2. python 数据类型三 (字典)

    一.字典的介绍 字典(dict)是python中唯一的一个映射类型,它是以{}括起来的键值对组成,在dict中key是唯一的,在保存的时候,根据key来计算出一个内存地址,然后将key-value保存 ...

  3. Android根据字符串型的资源名获取对应资源id

    有时候我们想动态的根据一个字符串资源名获得到对应的资源id,如根据不同的图片名称获得对应的图片,此时就应该考虑如何实现. 大家知道,在编译Android工程时,系统会自动生成一个静态资源类R,里面根据 ...

  4. Spring Boot log4j多环境日志级别的控制

    之前介绍了在<Spring boot中使用log4j>,仅通过log4j.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用D ...

  5. 链表(上):如何实现LRU缓存淘汰算法?

    一.什么是链表 和数组一样,链表也是一种线性表. 从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 链表中的每一个内存块被称为节点Node. ...

  6. Python(27)--文件相关处理的应用(增、删、改、查)

    文件名为message,文件内容如下: global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 info default ...

  7. 利用django-simple-captcha生成验证码

    参考文档 http://django-simple-captcha.readthedocs.io/en/latest/ django支持1.7+ 1.安装 pip install django-sim ...

  8. XAMPP中MySQL无法启动解决办法

    如图 问题出在mysql的路径上,其实报错已经讲得听清楚了 预期应该是这样 结果却是这样 所以解决办法当然就是修改这个路径,出现这个报错原因大多因为之前电脑装过mysql,所以电脑默认启动是原来的my ...

  9. WebDriver高级应用实例(9)

    9.1封装操作表格的公用类 目的:能够使自己编写操作表格的公用类,并基于公用类进行表格中的元素的各类操作 被测网页的网址的HTML代码: <html> <body> <t ...

  10. 给1~3年iOS开发 经验朋友们的一些建议(附BAT面试题)

    前言 由于笔者是做 iOS 开发的,因此本文也仅对做 iOS 的同行们有针对性,其他方向仅供参考. 1,如果你: 1~3年左右工作经验,本科,非计算机相关科班出生,学校又比较一般. 实习企业不理想没有 ...