模板方法模式
发布日期:2021-10-18 18:51:25
浏览次数:2
分类:技术文章
本文共 5813 字,大约阅读时间需要 19 分钟。
1. 概述
定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。
2. 模式中的角色
2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
3. 模式解读
3.1 模板方法类图
3.2 模板方法模式代码实现
////// 抽象类 /// public abstract class AbstractClass { // 一些抽象行为,放到子类去实现 public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); ////// 模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们推迟到子类去实现。 /// public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine("Done the method."); } } ////// 具体类,实现了抽象类中的特定步骤 /// public class ConcreteClassA : AbstractClass { ////// 与ConcreteClassB中的实现逻辑不同 /// public override void PrimitiveOperation1() { Console.WriteLine("Implement operation 1 in Concreate class A."); } ////// 与ConcreteClassB中的实现逻辑不同 /// public override void PrimitiveOperation2() { Console.WriteLine("Implement operation 2 in Concreate class A."); } } ////// 具体类,实现了抽象类中的特定步骤 /// public class ConcreteClassB : AbstractClass { ////// 与ConcreteClassA中的实现逻辑不同 /// public override void PrimitiveOperation1() { Console.WriteLine("Implement operation 1 in Concreate class B."); } ////// 与ConcreteClassA中的实现逻辑不同 /// 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 实现代码
////// 抽象类,定义冒泡排序的骨架 /// public abstract class BubbleSorter { private int operations = 0; protected int length = 0; ////// 冒泡排序算法 /// ///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; } /// /// 留给子类实现的交换位置方法 /// /// protected abstract void Swap(int index); ////// 留给子类实现的比较方法 /// /// ///protected abstract bool OutOfOrder(int index); } /// /// 整型类型的冒泡算法实现 /// public class IntBubbleSorter:BubbleSorter { private int[] array = null; ////// 用冒泡算法排序 /// /// ///public int Sort(int[] theArray) { array = theArray; length = array.Length; // 调用冒泡算法 return DoSort(); } /// /// 实现冒泡算法中的交换操作 /// /// protected override void Swap(int index) { int temp = array[index]; array[index] = array[index + 1]; array[index + 1] = temp; } ////// 实现冒泡算法中的比较操作 /// /// ///protected override bool OutOfOrder(int index) { return (array[index] > array[index + 1]); } } /// /// 浮点数类型的冒泡算法 /// public class FloatBubbleSorter:BubbleSorter { private float[] array = null; ////// 用冒泡算法排序 /// /// ///public int Sort(float[] theArray) { array = theArray; length = array.Length; // 调用冒泡算法 return DoSort(); } /// /// 实现冒泡算法中的交换操作 /// /// protected override void Swap(int index) { float temp = array[index]; array[index] = array[index + 1]; array[index + 1] = temp; } ////// 实现冒泡算法中的比较操作 /// /// ///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(); } }
转载地址:https://blog.csdn.net/u011153869/article/details/53392477 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月26日 17时57分55秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Javascript到PHP加密通讯的简单实现
2021-06-30
德国SNS交友/视频网站Poppen.de的技术架构分享
2021-06-30
UNIX环境编程
2021-06-30
一笔画问题【数据结构-图论】
2021-06-30
红黑树
2021-06-30
安装多个gcc
2021-06-30
Linux0.01内核根目录Makefile注释
2021-06-30
【CSDN2012年度博客之星】需要您的一票,感谢大家的支持
2021-06-30
PHP对于浮点型的数据需要用不同的方法去解决
2021-06-30
Tokyo Cabinet 安装
2021-06-30
Flink在美团的应用与实践听课笔记
2021-06-30
Java多线程的11种创建方式以及纠正网上流传很久的一个谬误
2021-06-30
JDK源码研究Jstack,JMap,threaddump,dumpheap的原理
2021-06-30
Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现
2021-06-30
javac编译原理和javac命令行的使用
2021-06-30
Unity使用UnityWebRequest实现本地日志上传到web服务器
2021-06-30
Unity使用RenderTexture实现裁切3D模型
2021-06-30
美术和程序吵架,原来是资源序列化格式设置不统一
2021-06-30
Unity iOS接SDK,定制UnityAppController
2021-06-30
Unity iOS接SDK前先要了解的知识(Objective-C)
2021-06-30