# 策略模式
# 什么是策略模式(一种行为模式)
策略,指的是可以实现目标的方案集合,在某些特定情况下,策略之间是可以相互替换
的。
比如我们在外卖平台上看到的这些优惠。满减、会员和红包等,每一个大项优惠都具体包含了多个优惠方案。如满减活动中,可以同时有满20减15、满50减30等。会员包含普通会员、超级会员等。
每一个优惠方式下面的多个优惠方案,其实都是一个策略。这些策略之间是相互排斥、可替换的。并且是有一定的优先级顺序的。
我们说日常生活中,我们要实现目标,有很多方案,每一个方案都被称之为一个策略。在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。这就是策略模式。
策略模式(Strategy Pattern),指的是定义一系列算法,将每一个算法封装起来,并让它们可以相互替换
。策略模式让算法独立于使用它的客户
而变化。
特别说明一下,策略模式只适用管理一组同类型的算法,并且这些算法是完全互斥的情况。也就是说任何时候,多个策略中只有一个可以生效的那一种。如满减中的满20减10与满30减20之间;普通会员折扣与超级会员折扣之间等。
在策略模式中,定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法,在这里,每一个封装算法的类我们都可以称之为策略(Strategy),为了保证这些策略的一致性,一般会用一个抽象的策略类来做算法的定义,而具体每种算法则对应于一个具体策略类。
# 为什么要使用策略模式
当解决一个问题的方法类变得臃肿,算法变得臃肿。改动任何一点点的代码都需要把所有的功能全部回归测试一遍。不利于快速的响应业务的变化。
久而久之,这段代码就变成了一段谁都不愿改,谁都不敢改的代码。俗称"屎山"。这种代码会使代码有极低的可读性、可维护性、可扩展性,并且回归成本较高。
# 特点
策略模式具有以下特点:
策略模式的关注点不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
策略模式中各个策略算法是平等的。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。
运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。
# 优缺点
策略模式可以充分的体现面向对象设计原则中的封装变化、多用组合,少用继承、针对接口编程,不针对实现编程等原则。
优点 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
缺点 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。这种策略类的创建及选择其实也可以通过工厂模式来辅助进行。
由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。可以通过使用享元模式在一定程度上减少对象的数量。