一、问题产生背景
当我们进行一系列处理时(员工工资核算,会员管理,计算器,优惠活动),会有很多相似的算法和处理过程,只是由于具体的算法的差异,导致必须不同处理。这些处理和客户端无关,我们可以把这些算法抽象,然后进行处理。之所以叫策略,基本含义就是
针对一个问题,采用一种处理策略。
二、策略模式的通常做法
1、将类似的算法分离,并抽象。
2、客户端选择算法(可以结合简单工厂模型,将矛盾转移到别的类里面)
3、Context调用算法。(Context是业务处理过程中的全部业务信息)
三、具体实例
我想要实现一个简单的计算器功能,首先我要面对的是+、-、*、/四则运算四个算法,我们可以将它抽象
public abstract class AbstractCalculation { public void Show() { Console.WriteLine("这里是一个具体的计算"); } public abstract int Calculation(int iInputLeft, int iInputRight); }
然后实现各个具体的运算(以+为示例,其它类似)
public class Plus : AbstractCalculation { public override int Calculation(int iInputLeft, int iInputRight) { return iInputLeft + iInputRight; } }
这样我们的抽象工作就完成了。
下面我们写上下文类(Context,包含业务处理的全部信息,变量以及操作)
public class Context { private int LeftOperator = 0; private int RightOperator = 0; private AbstractCalculation calculation = null; public Context(AbstractCalculation calculation, int iInputLeft, int iInputRight) { this.calculation = calculation; LeftOperator = iInputLeft; RightOperator = iInputRight; } public int Calculate() { Console.WriteLine("Start Calculate"); try { return calculation.Calculation(LeftOperator, RightOperator); } catch (Exception ex) { throw ex; } } }
我们为了简化客户端,采用简单工厂模式将选择的矛盾转义到SimpleFactory中
public class SimpleFactory { public static AbstractCalculation CreateCalculation(string oper) { switch (oper) { case "+": return new Plus(); case "-": return new Minus(); case "*": return new Mutiply(); case "/": return new Division(); default: throw new Exception("不支持的操作!"); } } }
最后进行组合调用:
class Program { static void Main(string[] args) { Console.WriteLine("策略模式Demo"); int intResult = 0; int leftOperator; int rightOperator; string oper; while (true) { Console.WriteLine("请输入第一个操作数:"); leftOperator = Convert.ToInt32( Console.ReadLine()); Console.WriteLine("请输入操作符:"); oper = Console.ReadLine(); Console.WriteLine("请输入第二个操作数:"); rightOperator = Convert.ToInt32(Console.ReadLine()); AbstractCalculation calculation = SimpleFactory.CreateCalculation(oper); Context context = new Context(calculation, leftOperator, rightOperator); intResult = context.Calculate(); Console.WriteLine("{0}{1}{2}={3}",leftOperator,oper,rightOperator,intResult); } } }
四、设计模式分析
优点:a、将与具体业务无关的算法分离,便于添加。通常的,因为面向对象语言的最小单位是类,我们最好是添加算法类,而不是修改算法类。
b、由于context层将算法分离,因此可以添加一些其他渠道的参数,或者添加特殊处理,或者添加日志等。
缺点:并没有解决需要选择算法的矛盾,因此需要结合其他的设计模式处理,就像本利中添加了一个简单工厂,将矛盾从客户端转移,如果需要进一步处理,可以采用反射+配置文件的方式,或者依赖注入。