大话设计模式-策略模式(2)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class Context
    {
        Strategy strategy;

        public Context(Strategy strategy) 
        {
            this.strategy = strategy;
        }

        public void ContextInterface() 
        {
            strategy.AlgorithmInterface();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    /// <summary>
    /// 抽象算法类
    /// </summary>
    abstract class Strategy
    {
        //算法方法
        public abstract void AlgorithmInterface();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class ConcreteStrategyA:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A实现");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class ConcreteStrategyB:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B实现");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class ConcreteStrategyC:Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法C实现");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class CashContext
    {
        CashSuper cs = null;

        public CashContext(string type) 
        {
            switch (type)
            {
                case "正常收费":
                    cs = new CashNormal();
                    break;
                case "满300返100":
                    cs = new CashReturn("300","100");
                    break;
                case "打8折":
                    cs = new CashRebate("0.8");
                    break;
            }
        }

        public double GetResult(double money)
        {
            return cs.acceptCash(money);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class CashNormal:CashSuper
    {
        public override double acceptCash(double money)
        {
            return money;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class CashReturn:CashSuper
    {
        public double moneyCondittion = 0.0d;
        public double moneyReturn = 0.0d;

        public CashReturn(string moneyCondittion, string moneyReturn) 
        {
            this.moneyCondittion = Convert.ToDouble(moneyCondittion);
            this.moneyReturn = Convert.ToDouble(moneyReturn);
        }

        public override double acceptCash(double money)
        {
            double result = money;
            if (money >= moneyCondittion)
            {
                result = money - Math.Floor(money / moneyCondittion) * moneyReturn;
            }
            return result;
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class CashRebate:CashSuper
    {
        private double moneyRebate = 1d;

        public CashRebate(string moneyRebate)
        {
            this.moneyRebate = Convert.ToDouble(moneyRebate);
        }

        public override double acceptCash(double money)
        {
            return money * moneyRebate;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 策略模式
            Context context;

            context = new Context(new ConcreteStrategyA());
            context.ContextInterface();

            context = new Context(new ConcreteStrategyB());
            context.ContextInterface();

            context = new Context(new ConcreteStrategyC());
            context.ContextInterface();

            Console.ReadLine();

            #endregion

            #region 策略与简单工厂结合模式

            double total = 0.0d;
            double totalPricess = 0d;

            Console.Write("请输入单价:");
            string price = Console.ReadLine();
            Console.Write("请输入数量:");
            string num = Console.ReadLine();
            Console.Write("请输入收费类型(1.正常收费,2.满300返100,3.打8折):");
            string type = Console.ReadLine();

            string strType = string.Empty;
            switch (type)
            {
                case "1":
                    strType = "正常收费";
                    break;
                case "2":
                    strType = "满300返100";
                    break;
                case "3":
                    strType = "打8折";
                    break;
            }

            CashContext csuper = new CashContext(strType);
            totalPricess = csuper.GetResult(Convert.ToDouble(price) * Convert.ToDouble(num));
            Console.WriteLine("单价:" + price + "数量:" + num + "合计" + totalPricess.ToString("0.00"));

            total = total + totalPricess;

            Console.ReadLine();

            #endregion
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyFactory
{
    abstract class CashSuper
    {
        public abstract double acceptCash(double money);
    }
}

策略模式

策略模式是一种定义了一系列算法的方法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。从概念上来看,所有这些算法都是完成的相同的工作,
只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合.

组成

—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

—具体策略角色:包装了相关的算法和行为。

—环境角色:持有一个策略类的引用,最终给客户端调用。
 
应用场景
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

优缺点

优点:
1、 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
2、 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
3、 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2、策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
posted @ 2016-03-09 11:21  如.若  阅读(310)  评论(0编辑  收藏  举报