该说strategy了,怎么说呢,单单就表现形式来讲与Strategy最像的就是Bridge模式了。
Strategy:是一个锥把可以使用多个锥头;
Bridge:是不同锥把可以使用多个锥头;
看一下类图:
当Bridge的左边只有一个时就退化为Strategy,我是非常同意这个观点的。有人把Bridge当Strategy介绍http://www.cnblogs.com/chengbo/archive/2007/07/18/426612.html#Post 我觉得文章还是不错的,但他把两者搞混了。当然了,也没必要穷究与概念,无论哪种模式,关键还是看适宜的客观情况恰当的运用。
其实Strategy 这个单词就告诉了我们这个模式背后的意义,就是将逻辑分层,策略是在一个逻辑层施加的策略。下一层逻辑,或者说每一个逻辑点的具体实现,与我无关。或者说两者没必要耦合在一起。其实也就是针对接口编程这种优秀思想的一个体现。
实现的话可以按照上图,策略是施加在Context类中,使用接口作为占位符,客户代码中指定一个实现接口的具体类,来使用策略类。
也可以使用一点COOL 的技术,比如说.Net中的委托,理解委托的一种好方式就是当作给方法的特征指定一个名称一个占位符。下面就委托实现Srategy的例子(其实只要使用委托本身就是使用Strategy,呵呵):
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
employee[] Employees=
{
new employee("Andrew",100),
new employee("Bob",50),
new employee ("jerry",80),
new employee ("Dannes",120),
new employee("Tom",110)
};
CompareOP eop = new CompareOP(employee.RhsIsGreater); // 注意New一个委托的用法,制定一个静态或实例的方法给它,参数和返回类型一定要匹配
BubbleSorter.sort(Employees, eop);
for (int i = 0; i < Employees.Length; i++)
Console.WriteLine(Employees[i].ToString());
Console.ReadLine();
}
}
delegate bool CompareOP(object a, object b); //可以在任何可以声明类的地方声明委托
class BubbleSorter
{
public static void sort(object[] sortArray, CompareOP rhsisGreater) //这一堆就是我们的策略
{
for (int i = 0; i < sortArray.Length; i++)
{
for (int j = 0; j < i; j++)
{
if (rhsisGreater(sortArray[i], sortArray[j])) //大小的逻辑不属于我们的策略,且有变化。使用委托延迟邦定
{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
}
class employee
{
private string name;
private decimal salary;
public employee(string name, decimal salary)
{
this.name = name;
this.salary = salary;
}
public override string ToString() //重写了 Tosring(),和本文无关不过很有用
{
return string.Format(name + ",{0:c}", salary);
}
public static bool RhsIsGreater(object lhs, object rhs)
{
employee Lhs = (employee)lhs;
employee Rhs = (employee)rhs;
return Lhs.salary < Rhs.salary;
}
}
}
上面是用Salary比较大小的,如果改为年龄决定大小呢,我们还用改变class BubbleSorter吗? 知道后邦定的好处了吧