Template Method 和 Strategy 策略模式
Template Method 模式和 Strategy 模式所有解决的问题是类似的,通常可以互换使用。不过 Template Mothod 模式使用抽象类来解决问题,而 Strategy 使用接口来解决问题。
Strategy 模式:为了遵循依赖倒置原则(DIP),我们想确保这个通用的算法不要依赖于具体实现,我们想要这个通用算法和具体实都依赖于抽象。
Template Method 模式允许一个通用算法操纵多个可能的具体实现,但是由于Strategy模式完全遵循DIP原则,从而允许每个具体实现都可以被多个不同的通用算法操纵。
以下例子中使用Strategy模式,可以实现多种排序算法,需要实现一个新的排序算法,只需要声明一个新的排序算法类。
一、Template Method(模板方法)
使用抽象类实现模板方法模式,把通用算法在抽象类中实现,细节定义为抽象方法,细节的具体实现放在派生类中
优势:所有派生类都能共用通用算法,派生类只需专注于抽象方法的具体实现。
缺点:继承是一种非常强的的关系,派生类不可避免的和他的基类绑定在一起。
Template Method 实现冒泡排序算法:

namespace DesignPatternsConsoleApp.TemplateMethod
{
/// <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);
}
}
namespace DesignPatternsConsoleApp.TemplateMethod
{
public class IntBubbleSorter : BubbleSorter
{
private int[] array = null;
public int Sort(int[] array)
{
this.array = array ?? new int[0];
length =this.array.Length;
return DoSort();
}
protected override bool OutOfOrder(int index)
{
return array[index] > array[index + 1];
}
protected override void Swap(int index)
{
int temp = array[index];
array[index] = array[index + 1];
array[index + 1] = temp;
}
}
}
namespace DesignPatternsConsoleApp.TemplateMethod
{
public class DoubleBubbleSorter : BubbleSorter
{
private double[] array = null;
public int Sort(double[] theArray)
{
array = theArray;
length = array.Length;
return DoSort();
}
protected override bool OutOfOrder(int index)
{
return array[index] > array[index + 1];
}
protected override void Swap(int index)
{
double temp = array[index];
array[index] = array[index + 1];
array[index + 1] = temp;
}
}
}
二、Strategy 策略模式
策略模式是将通用算法放在一个具体类中,把通用算法必须要调用的方法定义在接口中。由于Strategy模式完全遵循DIP原则,从而允许每个具体实现都可以被多个不同的通用算法操纵。

namespace DesignPatternsConsoleApp.Strategy
{
/// <summary>
/// 冒泡排序算法策略
/// </summary>
/// <typeparam name="T"></typeparam>
public class BubbleSorter<T>
{
private int operations = 0;
private int length = 0;
private ISortHandle<T> itsSortHandler = null;
public BubbleSorter(ISortHandle<T> handle)
{
itsSortHandler = handle;
}
public ISortHandle<T> ISortHandle
{
get => itsSortHandler;
}
public int Sort(T[] array)
{//通用算法,冒泡排序
itsSortHandler.SetArray(array);
length = itsSortHandler.Length();
operations = 0;
if (length <= 1)
{
return operations;
}
for (int nextToLast = length - 2; nextToLast >= 0; nextToLast--)
{
for (int index = 0; index <= nextToLast; index++)
{
if (itsSortHandler.OutOfOrder(index))
itsSortHandler.Swap(index);
operations++;
}
}
return operations;
}
}
}
namespace DesignPatternsConsoleApp.Strategy
{
/// <summary>
/// 冒泡排序策略2,如果数组已排序则不再重新排序
/// </summary>
public class QuickBubbleSorter<T>
{
private int operations = 0;
private int length = 0;
private ISortHandle<T> itsSortHandler = null;
public QuickBubbleSorter(ISortHandle<T> handle)
{
itsSortHandler = handle;
}
public ISortHandle<T> ISortHandle
{
get => itsSortHandler;
}
public int Sort(T[] array)
{
itsSortHandler.SetArray(array);
length = itsSortHandler.Length();
operations = 0;
if (length <= 1)
return operations;
bool thisPassInOrder = false;
for (int nextToLast = length - 2; nextToLast >= 0 && !thisPassInOrder; nextToLast--)
for (int index = 0; index <= nextToLast; index++)
{
if (itsSortHandler.OutOfOrder(index))
{
itsSortHandler.Swap(index);
thisPassInOrder = false;
}
operations++;
}
return operations;
}
}
}
namespace DesignPatternsConsoleApp.Strategy
{
public interface ISortHandle<T>
{//通过算法必须要调用的方法
void Swap(int index);
bool OutOfOrder(int index);
int Length();
void SetArray(T[] array);
}
}
namespace DesignPatternsConsoleApp.Strategy
{
public class SortHandle<T> : ISortHandle<T> where T : IComparable<T>
{
private T[] array = null;
public int Length()
{
return array.Length;
}
public bool OutOfOrder(int index)
{
return array[index].CompareTo(array[index + 1]) > 0;
}
public void SetArray(T[] array)
{
this.array = array;
}
public void Swap(int index)
{
var temp = array[index];
array[index] = array[index + 1];
array[index + 1] = temp;
}
}
}
浙公网安备 33010602011771号