服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 设计模式系列教程-模板方法模式

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

2021-11-23 15:03Wang Juqiang C#

模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码,子类实现算法的某些细节,有助于算法的扩展。

1. 概述

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

2. 模式中的角色

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

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

3. 模式解读

  3.1 模板方法类图

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

  3.2 模板方法模式代码实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/// <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 客户端代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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();
 }
}

  运行结果

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

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 实现类图

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

  6.2 实现代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/// <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 客户端调用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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();
 }
}

  运行结果

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

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

延伸 · 阅读

精彩推荐
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15