意圖
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。該模式使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
適用性
1、一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。
2、各子類中公共的行爲應被提取出來並集中到一個公共父類中以避免代碼重複。即“重分解以一般化”,首先識別現有代碼中的不同之處,並且將不同之處分離爲新的操作。最後,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
3、控制子類擴展。模板方法只在特定點調用“Hook Method(鉤子方法)”操作,這樣就只允許在這些點進行擴展。
結構圖
角色
抽象類(AbstractClass):實現了模板方法,定義了算法的骨架。
具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的算法。
優缺點
優點
模板方法模式通過把不變的行爲搬移到超類,去除了子類中的重複代碼。
子類實現算法的某些細節,有助於算法的擴展。
通過一個父類調用子類實現的操作,通過子類擴展增加新的行爲,符合“開放-封閉原則”。
缺點
每個不同的實現都需要定義一個子類,這會導致類的個數的增加,設計更加抽象。
實現
實現UML
實現代碼
/// <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]);
}
}
客戶端調用
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();
}
}