标签:实现 依赖注入 ring 避免 意思 new 替换 总结 应用
前面主题介绍的状态模式是对某个对象状态的抽象,而本文要介绍的策略模式也就是对策略进行抽象,策略的意思就是方法,所以也就是对方法的抽象,下面具体分享下我对策略模式的理解。
在现实生活中,策略模式的例子也非常常见,例如,中国的所得税,分为企业所得税、外商投资企业或外商企业所得税和个人所得税,针对于这3种所得税,针对每种,所计算的方式不同,个人所得税有个人所得税的计算方式,而企业所得税有其对应计算方式。如果不采用策略模式来实现这样一个需求的话,可能我们会定义一个所得税类,该类有一个属性来标识所得税的类型,并且有一个计算税收的CalculateTax()方法,在该方法体内需要对税收类型进行判断,通过if-else语句来针对不同的税收类型来计算其所得税。这样的实现确实可以解决这个场景吗,但是这样的设计不利于扩展,如果系统后期需要增加一种所得税时,此时不得不回去修改CalculateTax方法来多添加一个判断语句,这样明白违背了“开放——封闭”原则。此时,我们可以考虑使用策略模式来解决这个问题,既然税收方法是这个场景中的变化部分,此时自然可以想到对税收方法进行抽象。具体的实现代码见2.3部分。
前面介绍了策略模式用来解决的问题,下面具体给出策略的定义。策略模式是针对一组算法,将每个算法封装到具有公共接口的独立的类中,从而使它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象负责。策略模式通常把一系列的算法包装到一系列的策略类里面。用一句话慨括策略模式就是——“将每个算法封装到不同的策略类中,使得它们可以互换”。
下面是策略模式的结构图:
该模式涉及到三个角色:
下面就以所得税的例子来实现下策略模式,具体实现代码如下所示:
1 namespace StrategyPattern 2 { 3 // 所得税计算策略 4 public interface ITaxStragety 5 { 6 double CalculateTax(double income); 7 } 8 9 // 个人所得税 10 public class PersonalTaxStrategy : ITaxStragety 11 { 12 public double CalculateTax(double income) 13 { 14 return income * 0.12; 15 } 16 } 17 18 // 企业所得税 19 public class EnterpriseTaxStrategy : ITaxStragety 20 { 21 public double CalculateTax(double income) 22 { 23 return (income - 3500) > 0 ? (income - 3500) * 0.045 : 0.0; 24 } 25 } 26 27 public class InterestOperation 28 { 29 private ITaxStragety m_strategy; 30 public InterestOperation(ITaxStragety strategy) 31 { 32 this.m_strategy = strategy; 33 } 34 35 public double GetTax(double income) 36 { 37 return m_strategy.CalculateTax(income); 38 } 39 } 40 41 class App 42 { 43 static void Main(string[] args) 44 { 45 // 个人所得税方式 46 InterestOperation operation = new InterestOperation(new PersonalTaxStrategy()); 47 Console.WriteLine("个人支付的税为:{0}", operation.GetTax(5000.00)); 48 49 // 企业所得税 50 operation = new InterestOperation(new EnterpriseTaxStrategy()); 51 Console.WriteLine("企业支付的税为:{0}", operation.GetTax(50000.00)); 52 53 Console.Read(); 54 } 55 } 56 }
在.NET Framework中也不乏策略模式的应用例子。例如,在.NET中,为集合类型ArrayList和List<T>提供的排序功能,其中实现就利用了策略模式,定义了IComparer接口来对比较算法进行封装,实现IComparer接口的类可以是顺序,或逆序地比较两个对象的大小,具体.NET中的实现可以使用反编译工具查看List<T>.Sort(IComparer<T>)的实现。其中List<T>就是承担着环境角色,而IComparer<T>接口承担着抽象策略角色,具体的策略角色就是实现了IComparer<T>接口的类,List<T>类本身实现了存在实现了该接口的类,我们可以自定义继承与该接口的具体策略类。
在下面的情况下可以考虑使用策略模式:
策略模式的主要优点有:
策略模式的主要缺点有:
到这里,策略模式的介绍就结束了,策略模式主要是对方法的封装,把一系列方法封装到一系列的策略类中,从而使不同的策略类可以自由切换和避免在系统使用多重条件选择语句来选择针对不同情况来选择不同的方法。在下一章将会大家介绍责任链模式。
标签:实现 依赖注入 ring 避免 意思 new 替换 总结 应用
原文地址:http://www.cnblogs.com/kanekiken/p/7367352.html