簡單工廠搭配策略模式

簡單介紹一下這兩個設計模式。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。

相關文章
相關標籤/搜索