C# 设计模式系列教程-模板方法模式

1. 概述

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

2. 模式中的角色

  2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。

  2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。

3. 模式解读

  3.1 模板方法类图

  3.2 模板方法模式代码实现

 /// <summary>
 /// 抽象类
 /// </summary>
 public abstract class AbstractClass
 {
  // 一些抽象行为,放到子类去实现
  public abstract void PrimitiveOperation1();
  public abstract void PrimitiveOperation2();

  /// <summary>
  /// 模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们推迟到子类去实现。
  /// </summary>
  public void TemplateMethod()
  {
   PrimitiveOperation1();
   PrimitiveOperation2();
   Console.WriteLine("Done the method.");
  }
 }

 /// <summary>
 /// 具体类,实现了抽象类中的特定步骤
 /// </summary>
 public class ConcreteClassA : AbstractClass
 {
  /// <summary>
  /// 与ConcreteClassB中的实现逻辑不同
  /// </summary>
  public override void PrimitiveOperation1()
  {
   Console.WriteLine("Implement operation 1 in Concreate class A.");
  }

  /// <summary>
  /// 与ConcreteClassB中的实现逻辑不同
  /// </summary>
  public override void PrimitiveOperation2()
  {
   Console.WriteLine("Implement operation 2 in Concreate class A.");
  }
 }

 /// <summary>
 /// 具体类,实现了抽象类中的特定步骤
 /// </summary>
 public class ConcreteClassB : AbstractClass
 {
  /// <summary>
  /// 与ConcreteClassA中的实现逻辑不同
  /// </summary>
  public override void PrimitiveOperation1()
  {
   Console.WriteLine("Implement operation 1 in Concreate class B.");
  }

  /// <summary>
  /// 与ConcreteClassA中的实现逻辑不同
  /// </summary>
  public override void PrimitiveOperation2()
  {
   Console.WriteLine("Implement operation 2 in Concreate class B.");
  }
 }

  3.3 客户端代码

 class Program
 {
  static void Main(string[] args)
  {
   // 声明抽象类
   AbstractClass c;

   // 用ConcreteClassA实例化c
   c = new ConcreteClassA();
   c.TemplateMethod();

   // 用ConcreteClassB实例化c
   c = new ConcreteClassB();
   c.TemplateMethod();

   Console.Read();
  }
 }

  运行结果

5. 模式总结

  5.1 优点

    5.1.1 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。

    5.1.2 子类实现算法的某些细节,有助于算法的扩展。

    5.1.3 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

  5.2 缺点

    5.2.1 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。

  5.3 适用场景

    5.1 在某些类的算法中,用了相同的方法,造成代码的重复。

    5.2 控制子类扩展,子类必须遵守算法规则。

6. 模式举例: 用冒泡算法非别对整型数组、浮点数数组、日期数组实现排序。

  6.1 实现类图

  6.2 实现代码

 /// <summary>
 /// 抽象类,定义冒泡排序的骨架
 /// </summary>
 public abstract class BubbleSorter
 {
  private int operations = 0;
  protected int length = 0;

  /// <summary>
  /// 冒泡排序算法
  /// </summary>
  /// <returns></returns>
  protected int DoSort()
  {
   operations = 0;
   if (length <= 1)
   {
    return operations;
   }

   for (int nextToLast = length - 2; nextToLast >= 0; nextToLast--)
   {
    for (int index = 0; index <= nextToLast; index++)
    {
     if (OutOfOrder(index))
     {
      Swap(index);
     }

     operations++;
    }
   }

   return operations;
  }

  /// <summary>
  /// 留给子类实现的交换位置方法
  /// </summary>
  /// <param name="index"></param>
  protected abstract void Swap(int index);
  /// <summary>
  /// 留给子类实现的比较方法
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  protected abstract bool OutOfOrder(int index);
 }

 /// <summary>
 /// 整型类型的冒泡算法实现
 /// </summary>
 public class IntBubbleSorter:BubbleSorter
 {
  private int[] array = null;

  /// <summary>
  /// 用冒泡算法排序
  /// </summary>
  /// <param name="theArray"></param>
  /// <returns></returns>
  public int Sort(int[] theArray)
  {
   array = theArray;
   length = array.Length;
   // 调用冒泡算法
   return DoSort();
  }

  /// <summary>
  /// 实现冒泡算法中的交换操作
  /// </summary>
  /// <param name="index"></param>
  protected override void Swap(int index)
  {
   int temp = array[index];
   array[index] = array[index + 1];
   array[index + 1] = temp;
  }

  /// <summary>
  /// 实现冒泡算法中的比较操作
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  protected override bool OutOfOrder(int index)
  {
   return (array[index] > array[index + 1]);
  }
 }

 /// <summary>
 /// 浮点数类型的冒泡算法
 /// </summary>
 public class FloatBubbleSorter:BubbleSorter
 {
  private float[] array = null;

  /// <summary>
  /// 用冒泡算法排序
  /// </summary>
  /// <param name="theArray"></param>
  /// <returns></returns>
  public int Sort(float[] theArray)
  {
   array = theArray;
   length = array.Length;
   // 调用冒泡算法
   return DoSort();
  }

  /// <summary>
  /// 实现冒泡算法中的交换操作
  /// </summary>
  /// <param name="index"></param>
  protected override void Swap(int index)
  {
   float temp = array[index];
   array[index] = array[index + 1];
   array[index + 1] = temp;
  }

  /// <summary>
  /// 实现冒泡算法中的比较操作
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  protected override bool OutOfOrder(int index)
  {
   return (array[index] > array[index + 1]);
  }
 }

  6.3 客户端调用

 class Program
 {
  static void Main(string[] args)
  {

   // 对整型数组排序
   int[] intArray = new int[]{5, 3, 12, 8, 10};
   BubbleSorter.IntBubbleSorter sorter = new BubbleSorter.IntBubbleSorter();
   sorter.Sort(intArray);
   foreach (int item in intArray)
   {
    Console.Write(item+" ");
   }

   Console.WriteLine("");

   // 对浮点数排序
   float[] floatArray = new float[] { 5.0f, 3.0f, 12.0f, 8.0f, 10.0f };
   BubbleSorter.FloatBubbleSorter floatSorter = new BubbleSorter.FloatBubbleSorter();
   floatSorter.Sort(floatArray);
   foreach (float item in floatArray)
   {
    Console.Write(item + " ");
   }

   Console.Read();
  }
 }

  运行结果

以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • C#设计模式之单例模式实例讲解

    前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡"Design Pattern(设计模式)"? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻

  • C#设计模式之观察者模式实例讲解

    前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡"Design Pattern(设计模式)"? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻

  • C#设计模式之外观模式介绍

    1.在设计初期阶段,应该要有意识的将不同的两层分离,比如考虑数据访问层.业务逻辑层.表示层之间建立外观模式,这样可以为子系统提供简单一致的接口,使得耦合大大降低. 2.开发阶段,子系统内部由于不够重构变得非常复杂,增加外观模式可以屏蔽这个复杂性,并提供简单的接口. 3.维护一个遗留的大型系统,代码不好再维护时,使用外观模式也是不错的选择. 看看外观模式的结构图: Facade类定义:可以给高层系统提供简单的接口 复制代码 代码如下: class Facade { SubSystemOne one

  • C#设计模式之Template模板方法模式实现ASP.NET自定义控件 密码强度检测功能

    本文实例讲述了C#设计模式之Template模板方法模式实现ASP.NET自定义控件 密码强度检测功能.分享给大家供大家参考,具体如下: 一.理论定义 模板方法模式 预先定义实现了一些基本属性和方法,需要重新计算的部分,通过子类去重写 或  增加新方法来实现. 二.应用举例 需求描述: ASP.NET自定义控件有很多通用的属性和事件, 通过继承System.Web.UI.WebControls.WebControl类,可以实现自定义控件. WebControl拥有控件基本的方法和事件,让我们定义

  • 举例讲解C#编程中对设计模式中的单例模式的运用

    单例模式的介绍 说到单例模式,大家第一反应应该就是--什么是单例模式?,从"单例"字面意思上理解为--一个类只有一个实例,所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了,下面给出单例模式的一个官方定义:确保一个类只有一个实例,并提供一个全局访问点.为了帮助大家更好地理解单例模式,大家可以结合下面的类图来进行理解,以及后面也会剖析单例模式的实现思路: 为什么会有单例模式 看完单例模式的介绍,自然大家都会有这样一个疑问--为什么要有单例模式的?它在什么情况下使用的?从单例模式的

  • 详解C#设计模式编程中的模板方法模式使用

    一.引言 提到模板,大家肯定不免想到生活中的"简历模板"."论文模板"."Word中模版文件"等,在现实生活中,模板的概念就是--有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下载下来的简历模板的格式都是相同的,然而我们下载下来简历模板之后我们可以根据自己的情况填充不同的内容要完成属于自己的简历.在设计模式中,模板方法模式中模板和生活中模板概念非常类似,下面让我们就详细介绍模板方法的定义,大家可以根据生活中模板的概

  • 浅谈C#设计模式之代理模式

    代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口.根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理.远程代理.虚拟代理.缓冲代理等,它们应用于不同的场合,满足用户的不同需求 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using

  • 浅谈c#设计模式之单一原则

    单一原则: 程序设计时功能模块独立,功能单一更有助于维护和复用. 例如:个人计算机功能很多,如果想从中只拿出一个功能来制造一个新的东西是困难的.同时如果你的计算机开不机,同时你的计算器功能也不能用了. 在编程中如果一个类封装了太多功能和上面的结果是类似的. 单一职责原则 例1: 大家应该能看出来这个类图中的接口设计是有问题的,用户的属性和用户的行为没有分开.我们根据用户的属性和行为拆开这个接口. 重新拆分成两个接口,IUserBo 负责用户的属性,IUserBiz负责用户的行为.当我们实例化除U

  • 浅谈C#设计模式之开放封闭原则

    在软件设计模式证这种不能修改,但可以扩展的思想也是最重要的设计原则,他就是开放-封闭原则 (OCP) 对于程序设计而言,怎么的设计才能面对需求的改变却可以保持相对的稳定,从而可以使得系统可以再第一个版本的基础上不断的推出新版本呢? 答案是在程序设计的时候使用开放封闭原则.   但是设计的同时,绝对对修改的关闭是不可能的,无论模块是多么的封闭,都存在一些无法对之封闭的变化,既然不可以完全的封闭,设计人员必须对他设计的模块应该对哪种变换的封闭做出选择,他必须猜测出最有可能发生变换的种类,然后构造抽象

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

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

  • c#设计模式 适配器模式详细介绍

    后续内容将包括以下结构模式: 适配器模式(Adapter):Match interfaces of different classes合成模式(Composite):A tree structure of simple and composite objects装饰模式(Decorator):Add responsibilities to objects dynamically代理模式(Proxy):An object representing another object享元模式(Flywei

随机推荐