简单介绍一下这两个设计模式。java
策略模式的思想就是,当你要根据特定场景使用特定算法时,能够把用一个接口提供这个算法,不一样的场景对他进行不一样的实现。主流程经过不一样的实现类算法
来完成这个功能。设计模式
简单工厂就是根据一个type返回对应的对象。数组
简单工厂+策略模式就能够实现根据调用方传过来的type经过简单工厂获取到对数据操做的实现类,而后操做数据返回,当新增一个type时,能够很清晰解决,避免误改。性能
下面以一个计算器举例,其实这不是一个很好的例子。spa
public class CalculatorTest { /** * 调用方 */ @Test public void test() { double num1 = 1.1; double num2 = 2.0; double result = calculate(num1, num2, CaculatorType.ADD); System.out.println(result); } /** * 接收方 * @param type 计算方法类型,是一个枚举值 * @return 计算结果 */ public double calculate(double num1, double num2, CaculatorType type) { CalculatorFactory calculatorFactory = new CalculatorFactory();
//根据type获取计算器 Calculator calculator = calculatorFactory.getCalculator(type); return calculator.caculate(num1, num2); } }
这样作的好处就是将来新曾别的计算方法时,例如减法。思路很清晰,增长一个枚举值,增长一个减法的算法,设计
calculate 这个方法彻底不须要动,在实际的开发过程当中,咱们应该尽可能保证主流程不被修改,这样才会减小Bug,故障的发生。
下面看一下这个工厂类。
public class CalculatorFactory { private EnumMap<CaculatorType,Calculator> typeToCalculator = Maps.newEnumMap(CaculatorType.class); { //当方法容易实现时,能够用lambda表达式实现策略模式从而避免每次都要新建一个类 typeToCalculator.put(CaculatorType.ADD, (num1, num2) -> num1 + num2); typeToCalculator.put(CaculatorType.SUB, (num1, num2) -> num1 - num2); typeToCalculator.put(CaculatorType.MUL, (num1, num2) -> num1 * num2); typeToCalculator.put(CaculatorType.DIV, (num1, num2) -> num1 / num2); } public Calculator getCalculator(CaculatorType type){ return typeToCalculator.get(type); } }
常见的工厂类可能会用switch,可是我的感受用map的形式更好,首先时间复杂度为O(1)固然,实现类的数量不可能太多,性能提高不会很明显。code
可是可读性会高,根据类型去容器里取对象,新增或删除时,加一行或者删一行代码便可,还有两点可能与其余看过的版本不一样。对象
1.使用了java8支持的lambda表达式代替了实现类,若是代码较短,没必要新增一个类,用lambda表达式比较方便。blog
2.我这里用的map是EnumMap,固然也能够用TreeMap和HashMap也能够,用EnumMap的缘由是EnumMap底层会建立一个与CaculatorType实例
个数相等的数组来存储。若是是hashmap会建立一个2的n次方的数组,浪费空间,而且hashmap还须要hash寻找数据存放位置,而且有可能hash冲突。
使用TreeMap的话插入和查找的时间复杂度是O(logn)。而EnumMap的最大时间复杂度就是O(1),由于EnumMap底层建立一个和它元素数
同样大的数组,当put时,若是put的是CaculatorType.ADD,会将它放入底层数组索引为CaculatorType.ADD.ordinal()的位置,也就是0,ordinal()
表明第几个实例,取得时候也是取索引为0的对象,不经过任何计算,直接从数组拿,因此若是想用map能够考虑一下key适不适合用枚举,若是
适合用枚举,果断采用而且用EnumMap。