对于策略模式一直有个疑惑,众所周知,策略模式中包含,抽象策略类,具体策略类,环境类,然后我看很多博文的例子是商品促销之类的(例:https://www.jianshu.com/p/3d6a0054931d)
我的问题是:在选择具体策略行为时,我们不照样还是需要if-else或者switch来选择嘛???求解T_T
我们聊设计模式的时候,首先要明白两个问题:1、设计模式解决了什么问题?或则说为什么要这些设计模式?2、这些设计模式本身合理吗?或则说正确吗?只有理解了这两个问题的基础上,我们才能更好的去探讨和运用这些设计模式。
在面向对象的程序设计当中,我们经常遇到这些以下问题:对某个对象的封装是否合理? 粒度的划分是否适中?依赖关系的处理是否恰当?容易扩展吗?可以很好的复用吗?等等问题。1994年出版的《Design Patterns: Elements of Reusable Object-Oriented Software》提出和总结了对这些常见的软件设计问题的标准解决方案,就是我们现在所熟知的23种设计模式。现在我们就可以回答第一个问题了,设计模式是为了解决我们软件设计中遇到的一系列问题。
那么第二个问题的答案呢?其实隐藏在Martin的论文《Design Principles and Design Patterns》中。也就是我们常提到的SOLID准则。我们讨论某个设计模式的正确性或则说合理性的时候先看它是否遵循了软件设计的SOLID原则。结果是显而易见的。
好了,啰嗦了一大堆,现在回到问题的本身。策略模式的核心是允许程序运行中选择一个算法,最大的好处就是把算法本身和环境解耦了。就拿题主中的例子来说,书籍打九折,鼠标打八折,如果不使用策略模式,那么打折这个算法就变成了如果是书籍九折,如果是鼠标八折,等等。可以看到具体的折扣算法和商品类型(环境)紧密耦合了。一旦我们需要加一个衣服七折,同时修改书籍的折扣为八五折,那么我们需要修改已有的实现同时增加新的实现。这样违反了SOLID里面的开闭原则,对修改没有闭合;当然同时也违背了单一职责原则。而一旦我们使用了策略模式呢,我们可以很灵活的做到每次构建购买的context的时候去调整不同商品的折扣,同时可以很方便的增加不同的折扣方式而不影响已经存在的算法。完美的支持了开闭原则和单一职责原则。所以重点不是有没有If else或则switch case,而是在哪里使用if else或则switch case.
策略是把每个算法独立封装起来了,通过选择的条件去执行具体的策略,不代表用的时候就不用写if-else,这是两码事。
如果你觉得if-else不雅,你可以把if-else放到一个工厂类里,通过工厂去实例化对象,再交给策略类去执行。
如果你非纠结if-else,你可以用反射,将UI层传递的参数,实例化为具体对象,再给策略类去执行。
你总不能说,啊...你不能在UI层选择,我要的是什么都不选,你就知道我打几折......然后给我算出来多少钱。
默聊正解。策略模式只是把不同的行为进行抽象,使之有一个共同的接口,可互相替换。至于最终到底用哪个行为,还是面临一个选择的。