C# 設計模式系列教程-模板方法模式
1. 概述
定義一個操作中的算法的骨架,而將步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義算法的某些特定步驟。
2. 模式中的角色
2.1 抽象類(AbstractClass):實現(xiàn)了模板方法,定義了算法的骨架。
2.2 具體類(ConcreteClass):實現(xiàn)抽象類中的抽象方法,已完成完整的算法。
3. 模式解讀
3.1 模板方法類圖

3.2 模板方法模式代碼實現(xiàn)
/// <summary>
/// 抽象類
/// </summary>
public abstract class AbstractClass
{
// 一些抽象行為,放到子類去實現(xiàn)
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
/// <summary>
/// 模板方法,給出了邏輯的骨架,而邏輯的組成是一些相應的抽象操作,它們推遲到子類去實現(xiàn)。
/// </summary>
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
Console.WriteLine("Done the method.");
}
}
/// <summary>
/// 具體類,實現(xiàn)了抽象類中的特定步驟
/// </summary>
public class ConcreteClassA : AbstractClass
{
/// <summary>
/// 與ConcreteClassB中的實現(xiàn)邏輯不同
/// </summary>
public override void PrimitiveOperation1()
{
Console.WriteLine("Implement operation 1 in Concreate class A.");
}
/// <summary>
/// 與ConcreteClassB中的實現(xiàn)邏輯不同
/// </summary>
public override void PrimitiveOperation2()
{
Console.WriteLine("Implement operation 2 in Concreate class A.");
}
}
/// <summary>
/// 具體類,實現(xiàn)了抽象類中的特定步驟
/// </summary>
public class ConcreteClassB : AbstractClass
{
/// <summary>
/// 與ConcreteClassA中的實現(xiàn)邏輯不同
/// </summary>
public override void PrimitiveOperation1()
{
Console.WriteLine("Implement operation 1 in Concreate class B.");
}
/// <summary>
/// 與ConcreteClassA中的實現(xiàn)邏輯不同
/// </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();
}
}
運行結(jié)果

5. 模式總結(jié)
5.1 優(yōu)點
5.1.1 模板方法模式通過把不變的行為搬移到超類,去除了子類中的重復代碼。
5.1.2 子類實現(xiàn)算法的某些細節(jié),有助于算法的擴展。
5.1.3 通過一個父類調(diào)用子類實現(xiàn)的操作,通過子類擴展增加新的行為,符合“開放-封閉原則”。
5.2 缺點
5.2.1 每個不同的實現(xiàn)都需要定義一個子類,這會導致類的個數(shù)的增加,設計更加抽象。
5.3 適用場景
5.1 在某些類的算法中,用了相同的方法,造成代碼的重復。
5.2 控制子類擴展,子類必須遵守算法規(guī)則。
6. 模式舉例: 用冒泡算法非別對整型數(shù)組、浮點數(shù)數(shù)組、日期數(shù)組實現(xiàn)排序。
6.1 實現(xiàn)類圖

6.2 實現(xiàn)代碼
/// <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>
/// 留給子類實現(xiàn)的交換位置方法
/// </summary>
/// <param name="index"></param>
protected abstract void Swap(int index);
/// <summary>
/// 留給子類實現(xiàn)的比較方法
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
protected abstract bool OutOfOrder(int index);
}
/// <summary>
/// 整型類型的冒泡算法實現(xiàn)
/// </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;
// 調(diào)用冒泡算法
return DoSort();
}
/// <summary>
/// 實現(xiàn)冒泡算法中的交換操作
/// </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>
/// 實現(xiàn)冒泡算法中的比較操作
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
protected override bool OutOfOrder(int index)
{
return (array[index] > array[index + 1]);
}
}
/// <summary>
/// 浮點數(shù)類型的冒泡算法
/// </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;
// 調(diào)用冒泡算法
return DoSort();
}
/// <summary>
/// 實現(xiàn)冒泡算法中的交換操作
/// </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>
/// 實現(xiàn)冒泡算法中的比較操作
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
protected override bool OutOfOrder(int index)
{
return (array[index] > array[index + 1]);
}
}
6.3 客戶端調(diào)用
class Program
{
static void Main(string[] args)
{
// 對整型數(shù)組排序
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("");
// 對浮點數(shù)排序
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();
}
}
運行結(jié)果

以上就是本文的全部內(nèi)容,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#使用WebSocket與網(wǎng)頁實時通信的實現(xiàn)示例
本文主要介紹了C#使用WebSocket與網(wǎng)頁實時通信的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08
C# CAD SelectionFilter下TypedValue數(shù)組使用方式
這篇文章主要介紹了C# CAD SelectionFilter下TypedValue數(shù)組使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
C#實現(xiàn)TIF圖像轉(zhuǎn)PDF文件的方法
這篇文章主要介紹了C#實現(xiàn)TIF圖像轉(zhuǎn)PDF文件的方法,涉及C#使用TIFtoPDF工具實現(xiàn)pdf文件轉(zhuǎn)換的技巧,需要的朋友可以參考下2015-07-07

