代码改变世界

策略模式

2012-08-08 17:27  Mike.Jiang  阅读(365)  评论(0编辑  收藏  举报

一、概念

策略模式(Strategy):它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。

二,应用示例

    采用《大话设计模式》中的商场收银的例子,即在收银算法对某个商品,可能是正常收费也可能是打折收费,也有可能是满200返20的。

三,普通青年解决方案

    写一个条件判断,根据不同的收费类型,调用不同的收银方法

View Code
string type = "";
            switch (type) 
            {
                case "Nomal":
                    {
                        //具体正常收费方法
                        break;
                    }
                case "Discount": 
                    {
                        //具体打折收费方法
                        break;
                    }
                case "Rebate":
                    {
                        //具体返利收费方法
                        break;
                    }
            }

这样做如果变动很小时,也无可厚非。但是当有变动时,比如在添加或修改其中的某个具体分支时,势必会改同一个类同一个方法,当程序发布出去后,再做这样的改动出错的机率就会很大了(违反了开闭原则)。

四,文艺青年解决方案

View Code
    public abstract class CashStrategy
    {
        public virtual void Cash() { }
    }

    public class NomalCashStrategy:CashStrategy
    {
        public override void Cash() 
        {
            //具体正常收费方法
        }
    }

    public class DiscountCashStrategy : CashStrategy
    {
        public override void Cash()
        {
            //具体打折收费方法
        }
    }

    public class RebateCashStrategy : CashStrategy
    {
        public override void Cash()
        {
            //具体返利收费方法
        }
    }

    public class CashContext
    {
        private CashStrategy strategy;

        public CashContext(CashStrategy strategy) 
        {
            this.strategy = strategy;
        }

        public void Cash() 
        {
            this.strategy.Cash();
        }
    }

    --客户端代码
            string type = "";
            switch (type)
            {
                case "Nomal":
                    {
                        CashContext context = new CashContext(new NomalCashStrategy());
                        context.Cash();
                        break;
                    }
                case "Discount":
                    {
                        CashContext context = new CashContext(new DiscountCashStrategy());
                        context.Cash();
                        break;
                    }
                case "Rebate":
                    {
                        CashContext context = new CashContext(new RebateCashStrategy());
                        context.Cash();
                        break;
                    }
            }

这样做,将具体的各个方法独立出去,在变动时,可以独立变化,不会影响其它的方法。但是在添加新的策略方法时,还需要改动客户端方法。所以可以做如下的改动

View Code
    public abstract class CashStrategy
    {
        public virtual void Cash() { }
    }

    public class NomalCashStrategy:CashStrategy
    {
        public override void Cash() 
        {
            //具体正常收费方法
        }
    }

    public class DiscountCashStrategy : CashStrategy
    {
        public override void Cash()
        {
            //具体打折收费方法
        }
    }

    public class RebateCashStrategy : CashStrategy
    {
        public override void Cash()
        {
            //具体返利收费方法
        }
    }

    public class CashContext2
    {
        private CashStrategy strategy;

        public CashContext2(string cashType)
        {
            switch (cashType)
            {
                case "Nomal":
                    {
                        this.strategy = new NomalCashStrategy();
                        break;
                    }
                case "Discount":
                    {
                        this.strategy = new DiscountCashStrategy();
                        break;
                    }
                case "Rebate":
                    {
                        this.strategy = new RebateCashStrategy();
                        break;
                    }
            }
        }

        public void Cash() 
        {
            this.strategy.Cash();
        }
    }

    --客户端代码
            string type = "";
            CashContext2 context = new CashContext2(type);
            context.Cash();

这次改动解决的是创建一系列对象问题,也就是与简单工厂相结合。