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(); } }
运行结果
以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持我们。
您可能感兴趣的文章
- 01-10深入浅出23种设计模式
- 01-10TortoiseSVN使用教程
- 01-10C#编程中枚举类型的使用教程
- 01-10Python设计模式编程中的备忘录模式与对象池模式示例
- 01-10C#中的delegate委托类型基本学习教程
- 01-10dotNet中的反射用法入门教程
- 01-10详解C#的设计模式编程之抽象工厂模式的应用
- 01-10解析C#设计模式编程中的装饰者模式
- 01-10简单了解C#设计模式编程中的桥接模式
- 01-10C#编程中使用设计模式中的原型模式的实例讲解
阅读排行
本栏相关
- 01-10C#通过反射获取当前工程中所有窗体并
- 01-10关于ASP网页无法打开的解决方案
- 01-10WinForm限制窗体不能移到屏幕外的方法
- 01-10WinForm绘制圆角的方法
- 01-10C#实现txt定位指定行完整实例
- 01-10WinForm实现仿视频播放器左下角滚动新
- 01-10C#停止线程的方法
- 01-10C#实现清空回收站的方法
- 01-10C#通过重写Panel改变边框颜色与宽度的
- 01-10C#实现读取注册表监控当前操作系统已
随机阅读
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 01-10C#中split用法实例总结
- 01-10SublimeText编译C开发环境设置
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 04-02jquery与jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-11ajax实现页面的局部加载