引入:项目中涉及到工做流,固然这个工做流的实现是由用户根据不一样的策略或者说方式传入处理这个事件的人的审批链,后台在存储过程当中进行解析,而后生成最终的审批链,在系统中流转进行审批。 好比审批链: 张三 -> 李四 -> 王五算法
因为不少外部系统接入,因此系统提供多种审批链的生成方式供外部系统选择,好比 1. 已经定好的好审批链的(叫作模板)传入模板 ID 系统就能够根据传入的模板生成审批链; 2. 外部系统自定义审批链,则 外部系统直接传入审批 链,张三 -> 李四 -> 王五 ,咱们系统进行解析存储。数据库
最近坐在旁边的一哥们作这一块,因而乎这几天耳边老是“策略”二字。由于当时不了解策略模式,以为颇有趣,那么多处理方式如何能调用到目标类进行处理,因此昨晚1点多睡不着,决定来学习下这个设计模式- 策略模式。 设计模式
书中定义: 定义一系列的算法,将每个算法封装起来,并让它们能够互相替换。策略模式让算法独立于使用它的客户而变化,是一种对象的行为模式。下面以排序算法来学习下策略模式。ide
如图是网上找到的一段资料:学习
1. 策略模式通常包括一个环境类即为使用算法的角色,它在解决问题的时候采用多种策略。在其中维护一个抽象策略的引用实例,用于定义采用的所采用的策略,下文中定义类名为 Context。 测试
2. 抽象类或者接口,为所支持的算法声明抽象方法,是全部策略类的父类 ,咱们使用Sort。this
3. 具体的策略类,实现了上面的接口或者继承抽象类,实现其定义的抽象算法,在运行时具体类中的方法覆盖实现的抽象方法来完成某个业务处理。spa
(1) 环境类代码设计
package cn.aries.pattern.StrategyPattern; public class Context { private Sort sortStrategy; public Context(Sort sortStrategy) { this.sortStrategy = sortStrategy; } public int[] sort(int[] arr){ return sortStrategy.sort(arr); } }
(2) 策略接口代码code
package cn.aries.pattern.StrategyPattern; public interface Sort { public int[] sort(int[] arr); }
(3) 排序算法代码
a. 选择排序
package cn.aries.pattern.StrategyPattern; public class SelectionSort implements Sort { /** * 选择排序 */ @Override public int[] sort(int[] arr) { int len = arr.length; int temp; for (int i = 0; i < len; i++) { temp = arr[i]; int index = i; for (int j = i + 1; j < len; j++) { if (arr[j] < temp) { temp = arr[j]; index = j; } } arr[index] = arr[i]; arr[i] = temp; } System.out.println("this is selection sort !"); return arr; } }
b. 冒泡排序
package cn.aries.pattern.StrategyPattern; public class BubbleSort implements Sort{ /** * 冒泡排序 */ @Override public int[] sort(int[] arr) { int len = arr.length; for (int i = 0; i < len; i++) { for (int j = i+1; j < len; j++) { int temp; if(arr[i] > arr[j]){ temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } System.out.println("this is bubble sort !"); return arr; } }
c. 插入排序
package cn.aries.pattern.StrategyPattern; public class InsertionSort implements Sort { /** * 插入排序法 */ @Override public int[] sort(int[] arr) { int len = arr.length; for (int i = 1; i < len; i++) { int temp = arr[i]; int j; for (j = i; j > 0; j--) { if (arr[j - 1] > temp) { arr[j] = arr[j - 1]; } else { break; } } arr[j] = temp; } System.out.println("this is insertion sort !"); return arr; } }
(4) 测试代码
package cn.aries.pattern.StrategyPattern; public class App { public static void main(String[] args) { int[] arr = {8,4,5,2,62,2};
//具体的这个策略类调用能够在配置文件中设定,这里建立不一样的排序算法实例就会调用的不一样策略的排序算法 Sort sortStrategy = new SelectionSort(); Content content = new Content(sortStrategy); printArray(content.sort(arr)); } public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + ","); } } }
以上代码就是使用策略模式实现不一样排序方法的调用。若是引入新的排序算法,对系统无任何影响,之须要添加一个新的具体策略类,在该策略类中封装新的算法,而后修改对应的配置文件应用该策略便可。
优势:
1. 提供了对“开闭原则” 的完美支持,在不修改原代码的基础上,灵活的新增算法或者行为。
2. 其定义了一个算法或者行为族,能够将公用的代码提取到继承的父类中,从了避免了重复的代码。
3. 其将每一个算法或者行为封装为一个类,就是一个类只作一间事情,符合“单一职责”原则。
4. 能够避免使用多重条件转换语句if(){}else{},将选择使用什么算法的行为逻辑和算法分开,更易于维护。
缺点:
客户端必须知道全部的策略类,并自行的决定选择使用哪个策略类。客户端必须理解这些算法的区别,以便使用的使用选择恰当的算法类,就是策略模式只适用于客户端知道全部的算法和行为的状况。
1. 每个外部系统接入的时候,已经定义好了使用什么策略,而后将对应的策略写入数据库。
2. 每个策略类都配置在了xml文件中。
3. 当外部系统提交数据过来的时候,根据外部系统名称到数据库中查找当时接入系统时选择的策略名称 strategyName 。
4. 在要调用策略的位置使用上下午容器ac.getBean("strategyName");获取到具体的策略类,就能够根据客户需求使用目标算法或者方式完成业务流程,相似以下代码:
其实最终的结论,在使用策略的时候,一个业务可能有多中执行路径或者执行方式供选择(也就是多个策略),可是具体走那一条,仍是须要在调用的时候就间接的表示清楚,到此心中的谜团解开了。