设计模式-策略模式详解

1、引言git

在讲策略模式以前,咱们来看零售行业软件的一个针对客户类型打折的功能。github

vip客户打八折,svip客户打七折。算法

代码实现:ide

 if (customer == "vip")
 {
       amount = amount * 0.8;
 }
 else if (customer == "svip")
 {
       amount = amount * 0.7;
 }

看代码,挺简单的,可是若是今天vip打八折,明天要打7折,那还得改变原有的代码,这样就违背了开闭原则。这里变化的是折扣的计算方式(策略),策略模式就能够解决这类问题。this

2、概念spa

策略模式是一种对象行为型模式。策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并让它们能够相互替换。code

3、实现对象

策略模式包含三种角色:Context: 上下文类、Strategy: 抽象策略类、ConcreteStrategy: 具体策略类blog

抽象策略类:ip

    public abstract class AbstractDiscountStrategy
    {
        public abstract decimal Discount(decimal amount);
    }

具体策略类:

    public class VipDiscountStrategy:AbstractDiscountStrategy
    {
        public override decimal Discount(decimal amount)
        {
            return amount * 0.8M;
        }
    }
    public class SVipDiscountStrategy:AbstractDiscountStrategy
    {
        public override decimal Discount(decimal amount)
        {
            return amount * 0.7M;
        }
    }

环境类:

   public class StrategyContext
    {
        private AbstractDiscountStrategy discountStrategy;

        public StrategyContext(AbstractDiscountStrategy concreteDiscountStrategy)
        {
            this.discountStrategy = concreteDiscountStrategy;
        }

        public decimal ExecuteStrategy(decimal amount)
        {
            return this.discountStrategy.Discount(amount);
        }
    }

调用:

 if (customer == "vip")
            {
                context = new StrategyContext(new VipDiscountStrategy());
                amount = context.ExecuteStrategy(amount);
            }
            else if (customer == "svip")
            {
                context = new StrategyContext(new SVipDiscountStrategy());
                amount = context.ExecuteStrategy(amount);
            }

能够看到,应用策略模式后,若是要修改vip客户的折扣计算方式,只须要修改对应的策略便可,不须要修改客户端的调用代码,也不会影响到svip的折扣计算方式,符合开闭原则。

再来一个ssvip客户,只须要增长一个对应的策略实现类,而且修改客户端的调用方法便可。

vip和svip的策略能够互换。

4、总结

从上面的例子能够看出来,策略模式的优势是提供了对“开闭原则”的完美支持,用户能够在不修改原有系统的基础上选择算法或行为,也能够灵活地增长新的算法或行为。

缺点也很明显,客户端必须清楚知道每个策略的用途,而且自行决定使用哪个策略,增长了客户端的负担,这个问题能够使用配置的方式来解决。每个策略都须要一个类,会使策略类增多。

代码下载:https://github.com/hzhhhbb/Design-Patterns

相关文章
相关标签/搜索