.Net行为型设计模式之模板方法模式(Template Method)

一、动机(Motivate)

“模板方法”,就是有一个方法包含了一个模板,这个模板是一个算法。在我们的现实生活中有很多例子可以拿来说明这个模式,就拿吃饺子这个事情来说,要想吃到饺子必须经过三步,第一步是“和面”,第二步是“包馅”,第三步是“煮饺子”,这三步就是一个算法,我们要想吃到不同的面和馅的饺子,对这三步中的任意一步就行操作就可以,也可以完全定义这三步

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

二、意图(Intent)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。                                 ——《设计模式》GoF

三、结构图

四、模式的组成

模板方法模式参与者:

(1)、抽象类角色(AbstractClass):定义一个模板方法(TemplateMethod),在该方法中包含着一个算法的骨架,具体的算法步骤是PrimitiveOperation1方法和PrimitiveOperation2方法,该抽象类的子类将重定义PrimitiveOperation1和PrimitiveOperation2操作。

(2)、具体类角色(ConcreteClass):实现PrimitiveOperation1方法和PrimitiveOperation2方法以完成算法中与特定子类(Client)相关的内容。

在模板方法模式中,AbstractClass中的TemplateMethod提供了一个标准模板,该模板包含PrimitiveOperation1和PrimitiveOperation2两个方法,这两个方法的内容Client可以根据自己的需要重写。

五、模板方法模式的具体实现

下面以生活中吃饺子为例来实现模板方法模式。在现实生活中,做饺子的步骤都大致相同,如果我们针对每种饺子的做法都定义一个类,这样在每个类中都有很多相同的代码,为了解决这个问题,我们一般的思路肯定是把相同的部分抽象出来到抽象类中去定义,具体子类来实现具体的不同部分,这个思路也正式模板方法的实现精髓所在,具体实现代码如下:

static void Main(string[] args)
{
    //现在想吃绿色面的,猪肉大葱馅的饺子
    AbstractClass fan = new ConcreteClass1();
    fan.EatDumplings();

    Console.WriteLine();
    //过了段时间,我开始想吃橙色面的,韭菜鸡蛋馅的饺子
    fan = new ConcreteClass2();
    fan.EatDumplings();
}

//该类型就是抽象类角色--AbstractClass,定义做饺子的算法骨架,这里有三步骤,当然也可以有多个步骤,根据实际需要而定
public abstract class AbstractClass
{
    //该方法就是模板方法,方法里面包含了做饺子的算法步骤,模板方法可以返回结果,也可以是void类型,视具体情况而定
    public void EatDumplings()
    {
        MakingDough();//和面
        MakeDumplings();//包馅
        BoiledDumplings();  //煮饺子
        Console.WriteLine("饺子真好吃!");
    }

    public abstract void MakingDough();//要想吃饺子第一步肯定是“和面”---该方法相当于算法中的某一步
    public abstract void MakeDumplings();//要想吃饺子第二部是“包饺子”---该方法相当于算法中的某一步
    public abstract void BoiledDumplings(); //要想吃饺子第三部是“煮饺子”---该方法相当于算法中的某一步
}

//该类型是具体类角色--ConcreteClass,我想吃绿色面皮,猪肉大葱馅的饺子
public sealed class ConcreteClass1 : AbstractClass
{
    public override void MakingDough()  //要想吃饺子第一步肯定是“和面”---该方法相当于算法中的某一步
    {
        Console.WriteLine("在和面的时候加入芹菜汁,和好的面就是绿色的");//我想要面是绿色的,绿色健康嘛,就可以在此步定制了
    }

    public override void MakeDumplings()//要想吃饺子第二部是“包饺子”---该方法相当于算法中的某一步
    {
        Console.WriteLine("农家猪肉和农家大葱,制作成馅");//我想吃猪肉大葱馅的,在此步就可以定制了
    }

    public override void BoiledDumplings()//要想吃饺子第三部是“煮饺子”---该方法相当于算法中的某一步
    {
        Console.WriteLine("用我家的大铁锅和大木材煮饺子");//我想吃大铁锅煮的饺子,有家的味道,在此步就可以定制了
    }
}

//该类型是具体类角色--ConcreteClass2,我想吃橙色面皮,韭菜鸡蛋馅的饺子
public sealed class ConcreteClass2 : AbstractClass
{
    public override void MakingDough()//要想吃饺子第一步肯定是“和面”---该方法相当于算法中的某一步
    {
        Console.WriteLine("在和面的时候加入胡萝卜汁,和好的面就是橙色的");//我想要面是橙色的,加入胡萝卜汁就可以。在此步定制就可以了。
    }

    public override void MakeDumplings()    //要想吃饺子第二部是“包饺子”---该方法相当于算法中的某一步
    {
        Console.WriteLine("农家鸡蛋和农家韭菜,制作成馅");    //我想吃韭菜鸡蛋馅的,在此步就可以定制了
    }

    public override void BoiledDumplings()//要想吃饺子第三部是“煮饺子”---该方法相当于算法中的某一步
    {
        Console.WriteLine("可以用一般煤气和不粘锅煮就可以");   //此处没要求
    }
}

六、模板方法模式的实现要点:

Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展,是代码复用方面的基本实现结构。除了可以灵活应对子步骤的变化外,“Don't call me, let me call you(不要调用我,让我来调用你)”的反向控制结构是Template Method的典型应用。

1、模板方法模式适用情形:

(1)、 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
(2)、 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
(3)、 控制子类扩展。模板方法只允许在特定点进行扩展,而模板部分则是稳定的。

2、模板方法模式特点:

(1)、 TemplateMethod模式是一种非常基础性的设计模式,在面向对象系统中大量应用。它用最简洁的机制(基础、多态)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
(2)、 在具体实现方面,被TemplateMethod调用的虚方法可以具有实现,也可以没有任何实现(抽象方法或虚方法)。但一般推荐将它们设置为protected方法使得只有子类可以访问它们。
(3)、 模板方法模式通过对子类的扩展增加新的行为,符合“开闭原则”。

七、.NET 中模板模式的实现

这种模式在控件设计中大量的用到,比如:控件有自己的生命周期,Page对象也有自己的生命周期,Application应用对象也有自己的生命周期,这个生命周期里面的每个阶段其实就是模板方法里面包含的每个步骤,这些阶段步骤会被一个方法包含着,这个方法就是“模板方法”。让我们再说说控件吧,因为写好的控件,可能需要被开发人员自定义,那么在控件里我们已经定义好了控件呈现、动作的骨架,但是有些自定义的需求,需要延迟到扩展控件的开发人员来决定。    
当我们在做Windows应用程序的时候,就会使用Windows控件,那Windows控件是如何显示在Windows Form 上的呢,就需要一个OnPaint方法把控件画出来,这里OnPaint是一个虚方法的子步骤,这就是一个Template Method设计模式。如果我们不去重写这个OnPaint方法,它就有一个基本的默认实现,画一个空窗体。这里我们并没有调用OnPaint方法,而是Application的Run会进入Windows的消息循环结构,Paint就是一个消息。当我们移动一下窗口都会导致Paint事件的发生,并导致OnPaint函数的调用,这就是一种反向调用。当然,还有很多其他的子步骤可以提供扩展点,例如OnClose等,很多以On开头的全部都是Template Method模式的虚方法。 这个里面内容很复杂,它并不是用一个Template Method在里面调用所有的子步骤方法,它实际上是把整体的Template Method方法置于了一个消息循环的结构里面,我们可以把消息循环的结构看做模板方法里面的TemplateMethod公有非虚方法。

到此这篇关于.Net行为型设计模式之模板方法模式(Template Method)的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • .Net行为型设计模式之模板方法模式(Template Method)

    一.动机(Motivate) “模板方法”,就是有一个方法包含了一个模板,这个模板是一个算法.在我们的现实生活中有很多例子可以拿来说明这个模式,就拿吃饺子这个事情来说,要想吃到饺子必须经过三步,第一步是“和面”,第二步是“包馅”,第三步是“煮饺子”,这三步就是一个算法,我们要想吃到不同的面和馅的饺子,对这三步中的任意一步就行操作就可以,也可以完全定义这三步 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)

  • C#模板方法模式(Template Method Pattern)实例教程

    本文以一个简单的实例形式讲述了C#模板方法模式的实现方法,分享给大家供大家参考.具体实现方法如下: 这里假设要做一道红烧肉,做法有很多,在不同的做法中都有相同的部分,比如都要放油.放肉.放调料等.也有不同之处,比如有些做法放可乐,有些做法放甜蜜酱,等等. 先提炼出一个抽象类,该类不仅有制作红烧肉的各个步骤,而且还把各个步骤归纳到另一个方法,我们把这个方法称作模版方法.另外,在模版方法中,对于一些不确定的方面先用抽象方法. public abstract class HongShaoRou { p

  • Python设计模式之模板方法模式实例详解

    本文实例讲述了Python设计模式之模板方法模式.分享给大家供大家参考,具体如下: 模板方法模式(Template Method Pattern):定义一个操作中的算法骨架,将一些步骤延迟至子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 下面是一个模板方法模式的一个demo: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式--模板

  • Java设计模式模板方法模式(Template)用法解析

    这篇文章主要介绍了Java设计模式模板方法模式(Template)用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言: 我们在开发中有很多固定的流程,这些流程有很多步凑是固定的,比如JDBC中获取连接,关闭连接这些流程是固定不变的,变动的只有设置参数,解析结果集这些是根据不同的实体对象"来做调整",针对这种拥有固定算法流程,其中有固定的步凑,存在不固定的步凑的情况下就诞生了模板方法模式. 模板方法模式(Template)定义

  • PHP设计模式之模板方法模式定义与用法详解

    本文实例讲述了PHP设计模式之模板方法模式定义与用法.分享给大家供大家参考,具体如下: 什么是模板方法模式 模板方法(Template Method)设计模式中使用了一个类方法templateMethod(), 该方法是抽象类中的一个具体方法, 这个方法的作用是对抽象方法序列排序,具体实现留给具体类来完成.关键在于模板方法模式定义了操作中算法的"骨架",而由具体类来实现. 什么时候使用模板方法 如果已经明确算法中的一些步骤, 不过这些步骤可以采用多种不同的方法实现, 就可以使用模板方法

  • .Net行为型设计模式之策略模式(Stragety)

    目录 一.动机(Motivate) 二.意图(Intent) 三.结构图(Structure) 四.模式的组成 五.策略模式的代码实现 六.策略模式的实现要点: 1.策略模式的主要优点有: 2.策略模式的主要缺点有: 3.在下面的情况下可以考虑使用策略模式: 七..NET 策略模式的实现 一.动机(Motivate) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持不使用的算法也是一个性能负担.如何在运行时根据需要透

  • Java行为型设计模式之模板方法详解

    目录 模板方法模式 应用场景 主要角色 优缺点 模板方法模式的基本使用 创建抽象模板角色 创建具体实现 客户端调用 模板方法模式 模板方法模式属于行为型设计模式.它是指定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模板方法模式实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果. 模板方法模式的本质是抽象封装流程,具体进行实现. 应用场景 当完成一个操作具有固定的

  • Java经典设计模式之模板方法模式定义与用法示例

    本文实例讲述了Java设计模式之模板方法模式.分享给大家供大家参考,具体如下: 我们在生活中,很多事情都包含特定的一些步骤.如去银行办理业务,通常步骤的次序是:取号 –> 填单 –> 等待叫号–>办理业务.这几个步骤中,有的是不变的,比如取号,每个人都要取,但有的是要变的,比如都有填单,但是根据不同的业务,填写的单据不同.又比如我们外出吃饭,一般的步骤是:点餐–>等待–>吃饭–>付钱,也能发现同样的规律.这样的事情数不胜数. 项目开发中,也可能遇到这样的情况,多个功能模

  • C++设计模式之模板方法模式

    前言 离开了自己工作了将近两年的公司,日子不再有了忙碌,可以闲下来,躺在家里的床上,想着以后的路怎么走,说实话,真的很迷茫,从2012年毕业到现在,时间不长,但是学到的东西真的是非常有限,一直从事于Windows平台上的开发.说到Windows平台的开发,大家都肯定知道的HOOK的,即使不知道HOOK,对于COM应该也是知道的,我的系列博文中也对COM进行过全面的总结.说白了,HOOK就是在执行某个功能时,会有一个一系列的执行过程,对于这个过程一般都是固定的,比如:第一步执行什么,第二步干什么,

  • Android编程设计模式之模板方法模式详解

    本文实例讲述了Android编程设计模式之模板方法模式.分享给大家供大家参考,具体如下: 一.介绍 在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是,某些步骤的具体实现是未知的,或者说某些步骤的实现是会随着环境的变化而改变的,例如,执行程序的流程大致如下: 1.检查代码的正确性: 2.链接相关的类库: 3.编译相关代码: 4.执行程序. 对于不同的程序设计语言,上述4个步骤都是不一样的,但是,它们的执行流程是固定的,这类问题的解决方

随机推荐