在上一篇中的装饰者模式学习中,我学习到了一个新的技能就是通过对类的组装来扩展对象的行为,今天我来再来学一篇新的设计模式-——策略模式,这个模式也是一个对象行为模式
1:什么是策略模式
定义:策略模式属于对象的行为模式,用意是针对一组算法,然后将每一个算法封装到具有共同接口的具体类中,从而是这些算法可以相互替换
应用场景:在我们的国家,上班族,公司的收入都需要缴税,个人有个人所得税计算公式,民营企业有民营企业的所得税计算公式,外资企业有外资企业所得税的计算方式,这些计算公式都不一样,但是这些公式的责任都是一样的,那就是完成,要交纳给国家多少钱
场景分析:每一个计算公式都是一个具体的算法,而我们的国家就是一个所得税计算公式的入口
类图:
从类图中我可以看出这个设计模式的核心就是Context 这个入口的类和Strategy这个算法抽象接口
2:如何实现策略模式
这个模式比较简单,我们就不做过多的文字解释,还是老规矩,直接写code,(这几个税收的公式纯属demo演示,不是国家发布的标准)大家重在理解,策略模式的思想
1:创建税收总入口类(Context)
2:创建算法的共同接口(Strategy)
3:创建个人所得税的算法类
4:创建民营公司所得税的算法类
5:创建外资企业所得税的算法类
6:创建测试类
7:下图是我门的测试结果
通过上面的测试结果,我门可以发现,在整个设计过程中,
1):每一个算法都是独立的,互不干涉的类,在具体的算法类中只是单纯的维护了算法本身与他的职责进行了完全的分离。
2):每个算法的职责都维护在了我们的context类中,在这个类通过维护一个算法共同接口的引用使得具体的算法本身与算法的职责解耦合
3:策略模式在Spring 中的使用
在Spring 中实例化Bean的过程就是使用的策略模式,
AbstractAutowireCapableBeanFactory就等价于我们的context入口类,InstantiationStrategy是具体实例化Bean算法上层接口,SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy是二个具体的实例化Bean对象的算法类,下面简单的描述一下这几个类的工作流程,更详细的步鄹,大家可以看下spring的源码。
当AbstractAutowireCapableBeanFactory中的getInstantiationStrategy方法被触发后,就会调用InstantiationStrategy中的instantiate,因为在CglibSubclassingInstantiationStrategy中没有实现方法instantiate,所以会先调用父类的instantiate,然后在这个方法内根据类是否配置lookup-method或者replaced-method标签或者@Lookup注解,而调用两种不同的方式实例化bean。
4:策略模式的优缺点
优点:
通过将算法本身单独的封装使得每个算法之间可以自由切换
通过对具体算法的抽象使的整个模式的扩展性好,当有新的算法加入时只需要实现strategy接口即可
缺点:
策略类数量会大量增多,但复用性却很小
所有的策略都需要对外暴露,上层模块必须知道有哪些策略