每日一个设计模式(策略模式 -2011.4.18 星期一)期待提问和讨论
每天一个设计模式(策略模式 -2011.4.18 星期一)期待提问和讨论
在昨天的帖子里用简单工厂模式的方法实现了一个简单的计算功能
有同修积极回帖并提出用 策略模式 来实现更为适合
所以今天的模式就用策略模式实现昨天的计算功能
策略模式特点:定义算法家族,分别封装,互相可以替换,让算法的变化不影响使用算法的客户(代码)
可以看出策略模式和简单工厂模式非常的相似
最明显的区别的工厂模式在自己内部判断应该实例化哪个类
而策略模式把这个工作放到了外部,也就是客户
如
if(operation=="+")
new conText(new OperationAdd()).ContextInterface();
------解决方案--------------------
这个好像是那个设计模式那本书的
------解决方案--------------------
C#提供了委托和Lambda表达式。所以可以用极其精简的代码实现策略模式。
甚至都看不出来是策略模式(也可以说不用任何模式,但是这样lz不爱听,如同一条线的长度为0,线退化成一个点,但是你也可以称为一条长度为0的线,其实已经没有线了)。
有时间给大家做个演示,如何用C#3和4特有的语法代替大部分设计模式。因为绝大多数人都把C#当作C/C++或者Java的兼容版本来看待C#的,虽然也能写出正确的程序,但是如同外国人说中文一样,有生涩的感觉。
在昨天的帖子里用简单工厂模式的方法实现了一个简单的计算功能
有同修积极回帖并提出用 策略模式 来实现更为适合
所以今天的模式就用策略模式实现昨天的计算功能
- C# code
namespace 策略模式 { //抽象算法类 abstract class Operation { private double _leftNum; public double LeftNum { get { return _leftNum; } set { _leftNum = value; } } private double _rightNum; public double RightNum { get { return _rightNum; } set { _rightNum = value; } } public double GetResult(); } //具体算法1 继承抽象算法类 public class OperationAdd : Operation { public override double GetResult() { double result = 0; result = LeftNum + RightNum; return result; } } public class OperationSub : Operation { public override double GetResult() { double result = 0; result = LeftNum + RightNum; return result; } } public class OperationMul : Operation { public override double GetResult() { double result = 0; result = LeftNum * RightNum; return result; } } public class OperationDiv : Operation { public override double GetResult() { double result = 0; if (LeftNum == 0) { throw new Exception("除数不能为 0。"); } result = LeftNum / RightNum; return result; } } public class OperationSqr : Operation { public override double GetResult() { double result = 0; result = LeftNum * LeftNum; return result; } } public class OperationSqrt : Operation { public override double GetResult() { double result = 0; if (LeftNum == 0) { throw new Exception("负数不能开平方根。"); } result = Math.Sqrt(LeftNum); return result; } } public class OperationReverse : Operation { public override double GetResult() { double result = 0; result = -LeftNum; return result; } } //上下文,用来维护一个对 算法 的引用 public class Context { Operation _op; public Context(Operation op) { _op = op; } public void ContextInterface() { _op.GetResult(); } } }
策略模式特点:定义算法家族,分别封装,互相可以替换,让算法的变化不影响使用算法的客户(代码)
可以看出策略模式和简单工厂模式非常的相似
最明显的区别的工厂模式在自己内部判断应该实例化哪个类
而策略模式把这个工作放到了外部,也就是客户
如
if(operation=="+")
new conText(new OperationAdd()).ContextInterface();
------解决方案--------------------
这个好像是那个设计模式那本书的
------解决方案--------------------
C#提供了委托和Lambda表达式。所以可以用极其精简的代码实现策略模式。
甚至都看不出来是策略模式(也可以说不用任何模式,但是这样lz不爱听,如同一条线的长度为0,线退化成一个点,但是你也可以称为一条长度为0的线,其实已经没有线了)。
有时间给大家做个演示,如何用C#3和4特有的语法代替大部分设计模式。因为绝大多数人都把C#当作C/C++或者Java的兼容版本来看待C#的,虽然也能写出正确的程序,但是如同外国人说中文一样,有生涩的感觉。
- C# code
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine(CalcByBinaryOperator<int>(4, 5, (x, y) => x + y)); Console.WriteLine(CalcByBinaryOperator<float>(4.5f, 5f, (x, y) => x - y)); Console.WriteLine(CalcByBinaryOperator<double>(4f, 0.5f, (x, y) => Math.Pow(x, y))); } static T CalcByBinaryOperator<T>(T left, T right, Func<T, T, T> Strategy) { return Strategy(left, right); } } }