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、总结
从上面的例子能够看出来,策略模式的优势是提供了对“开闭原则”的完美支持,用户能够在不修改原有系统的基础上选择算法或行为,也能够灵活地增长新的算法或行为。
缺点也很明显,客户端必须清楚知道每个策略的用途,而且自行决定使用哪个策略,增长了客户端的负担,这个问题能够使用配置的方式来解决。每个策略都须要一个类,会使策略类增多。