设计模式-策略模式Strategy以及消灭if else
2017-08-01 11:55
423 查看
概述
如果在开发过程中,出现大量的if else或者switch case 语句,如果这些语句块中的代码并不是包含业务逻辑,只是单纯的分流方法,那么,每一个语句块中都是一个算法或者叫策略。背景
比如在最近项目中遇到的问题。一个二维码字符串解析的方法:微信的二维码扫描结果包含“WeChat”,解析规则是拿着文本到微信服务器解析,返回解析对象。
支付宝二维码扫描结果包含“Alipay”,解析规则是使用“->”分割字符串得到解析对象。
最简单快速的代码就是直接if else判断:
1 /// <summary> 2 /// 解析方法 3 /// </summary> 4 /// <param name="text">扫描得到的文本</param> 5 public void AnalysisAction(string text) 6 { 7 //微信解析方法 8 if (text.Contains("WeChat")) 9 { 10 //拿着text到微信服务器解析,返回解析对象。 11 } 12 //支付宝解析方法 13 else if (text.Contains("Alipay")) 14 { 15 //使用->分割,得到解析对象。 16 } 17 }
问题
当然使用这种方式是可以的,但是如果以后又加入一种扫码解析方法:中国联通二维码扫描文本中包含“Unicom”,解析规则为以“:”分割,得到解析对象。
那么你就要继续添加else if(text.Contains("Unicom"))。每次增加一个新的扫描解析规则,你都要去增加else if判断,这种是面向过程的体验,属于硬编码。这也违反了面向对象的开闭原则。
改进(抽象)
我们可以使用策略模式来改进代码。定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。抽象出一个扫描解析接口,定义一个解析方法。然后分别定义微信和支付宝的解析方法集成接口。
策略模式的uml图如下:
public class StrategyContext3 { private readonly IList<IStrategy> strategyList = new List<IStrategy>(); /// <summary> /// 将所有策略都方法 /// </summary> /// <param name="text"></param> public StrategyContext3(string text) { //查询程序集 Assembly assembly = Assembly.GetExecutingAssembly(); //找出继承扫描策略接口的类 IEnumerable<Type> types = assembly.GetTypes().Where(c => c.GetInterface("IStrategy") != null); foreach (var t in types) { object[] parameters = new object[1]; parameters[0] = text; //创建类的实例 strategyList.Add((IStrategy)Activator.CreateInstance(t, parameters)); } } /// <summary> /// 调用具体的策略类实现扫码解析方法 /// </summary> public void AnalysisAction() { foreach (var item in strategyList) { if (item.Analysisable)//判断当前策略类是否可以处理 item.AnalysisAction(); } } }
context
应用场景
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
总结
优点:策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。缺点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。 这也就是我们所说的if else并没有真正的被消灭。
改进:我们可以将决定使用哪种策略的权利放到策略类本身中,让策略自己决定到底是不是用我自己的方法。从而实现消灭if else。
可以通过反射,反射出所有的策略。这样比较符合开闭原则。
相关文章推荐
- 设计模式——行为型模式之借助策略模式(Strategy Pattern)减少使用不必要的if-else if -else和switch-case(三)
- Android设计模式 -- 巧用策略模式告别过多的 if...else...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- [转载]设计模式--策略模式(Strategy)
- Java设计模式十: 策略模式(Strategy)
- C++设计模式--Strategy策略模式
- C#设计模式系列:策略模式(Strategy)
- 设计模式 学习笔记 之 策略模式 Strategy(4)
- 设计模式之策略模式(strategy)
- 用设计模式来代替臃肿的ifelse层层判断 .
- iOS 设计模式之策略模式( Strategy)
- 设计模式学习笔记二:Strategy,策略模式
- php设计模式 Strategy(策略模式)
- 设计模式C++实现(2)——策略模式(strategy)
- 设计模式-策略模式(Strategy)
- Java设计模式-策略模式(strategy)
- 浅学设计模式--策略(Strategy)模式
- 设计模式之策略模式(Strategy)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式之(Strategy)策略模式