意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。该模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性
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();
}
}