日期:2014-05-20  浏览次数:20721 次

每天一个设计模式(策略模式 -2011.4.18 星期一)期待提问和讨论
在昨天的帖子里用简单工厂模式的方法实现了一个简单的计算功能
有同修积极回帖并提出用 策略模式 来实现更为适合
所以今天的模式就用策略模式实现昨天的计算功能

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);
        }
    }
}