简单工厂搭配策略模式

简单介绍一下这两个设计模式。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。

相关文章
相关标签/搜索