应用背景: 系统中存在数据相关的统计模块,该统计模块从最开始只包含资讯类数据的统计逐步扩展至全字段类数据统计,后来又增加了其他系统基本上所有接口都相同的统计功能,差异性在于统计需要的客户人员数量的不同。故可以引入策略模式来优化大量相同逻辑相同接口不同的数据统计功能。
示例:
此上下文环境类用来对于客户端提供访问策略功能接口, 其中构造函数用来注入子策略实现类的实例, 每个接口的实现在Strategy的基类中都有实现。
策略基类实现节选一:
首先最上部定义了一些需要存储在Redis中使用的key,构造函数用来注入对象
策略基类实现节选二:
这里是较为设计核心所在,将存储在不同Redis中的key 使用抽象类的方式编写在基类中,实际实现交由子类实现,在客户端使用不同的策略时 可以自动的执行对应子类中的Redis的key,但主逻辑完全可以交由策略基类来实现
以基类中其中一个较为简单的方法进行说明:
该方法的作用是进行收集相关数据,然后SetToRedis() 编写到缓存中。 因为系统中存在不同的统计类型,故使用的Redis key是分开独立的。但每种统计的页面和数据结构都是类似的
故这里主逻辑是在基类中编写,setToRedis()方法是抽象类,具体的实现交由子类实现 以实现向不同指定的Key中写入指定格式的数据。 具体执行时使用哪种则由调用方客户端决定。
**策略模式的功能是把具体的算法实现从具体的业务处理中独立出来,把它们实现称为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换
**重心是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
如果存在多个if-else语句可以考虑使用策略模式,策略模式就是把各个平等的具体实现封装到单独的策略实现类,然后通过上下文来与具体的策略类进行交互
*策略模式对于一系列具体的策略算法,大家的地位是完全一样的,正因为如此才实现了算法之间可以相互替换的特点。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。
**策略算法是相同行为的不同实现
综上优缺点:
优点
1、定义一系列算法: 实现让这些算法可以相互替换。为这一系列算法定义公共的接口,以约束一系列算法要实现的功能。具有的公共功能,可以把策略接口实现成为抽象类。
2、避免多重条件语句: 策略模式的一系列策略算法是平等的,是可以互换的。
缺点
1、客户必须了解每种策略的不同
客户端来选择具体使用哪种策略,就需要客户了解所有的策略,就需要客户了解所有的策略,还要了解各种策略的功能和不同,这样才能做出正确的选择,而且这样也暴露了策略的具体实现。
2、增加了对象数目
3、只适合扁平的算法结构
一个策略接口下,有多个平等的策略算法,就相当于兄弟算法。而且在运行时刻只有一个算法被使用,这就限制了算法使用的层级,使用的时候不能嵌套使用。
**本质: 分离算法,选择实现
从设计原则上来看,策略模式很好地体现了开一闭原则。策略模式通过把一系列可变的算法进行封装,并定义出合理的使用结构,使得在系统出现新算法的时候,能很容易地把新的算法加入到已有的系统中,而已有的实现不需要做任何修改。
策略模式还很好地体现了里氏替换原则。策略模式是一个扁平结构,一系列的实现算法其实是兄弟关系,都是实现同一个接口或者继承的同一个父类。这样只要使用策略的客户保持面向抽象类型编程,就能够使用不同策略的具体实现对象来配置它,从而实现一系列算法可以相互替换