1. 程式人生 > >JAVA設計模式什麼鬼(策略)——作者:凸凹裡歐

JAVA設計模式什麼鬼(策略)——作者:凸凹裡歐

策略,Strategy,古時也稱“計”,為了達成某個目標的方案,目標不同,方案也隨之更改。例如特工執行任務時總要準備好幾套方案以應對突如其來的變化,A計劃實施過程中情況突變導致預案無法繼續實施,則馬上更換為B計劃,正所謂計劃不如變化快,提前策劃固然非常重要,而隨機應變更是不可或缺,只有保證這種可變的靈活性才能立於不敗之地。世界永遠都在變,唯一不變的就是變本身。

作為有思想的碼農,我們當然也不能把程式寫死了,一個設計優秀的系統,絕不是把現有類的程式碼改來改去,而一定是擴充套件類並接入系統,這樣馬上就能適應不同的使用者需求。

就拿遊戲機來舉個例子,早期的俄羅斯方塊風靡全球,後來國內流行一種掌機,只能玩俄羅斯方塊這一個遊戲,可過不了多久大家就玩膩了,於是熱度降低這種遊戲機很快就退出市場了,顯然這是一種失敗的設計模式。

後來任天堂出品的Game Boy以及Sony的PSP則完全帶來了不同的使用者體驗,系統提供了統一的卡槽介面,玩家只要更換卡帶或MD就可以達到更換遊戲的目的,做到了一機多用。

各種遊戲卡帶,更換遊戲方便多了。

好了,開始實戰部分,為了說明問題,我們繼續發揚極簡主義的優良傳統,我們就做一個最簡單的計算器好了,假設我們的計算器只能進行加減法,程式碼如下。

1 public class Calculator {//違反設計模式原則的做法
2    public int add(int a, int b){//加法
3        return a + b;
4    }
5
6    public int sub(int a, int b){//減法
7        return a - b;
8    }
9 }

這樣寫ok嗎?我們往後的擴充套件想想,如果隨著我們的演算法不斷增加,如乘法、除法、次方、開方等等,那麼這個計算器類就得不斷的改啊改啊,每次升級演算法我們都要把機器給拆開然後更改類程式碼,這豈不是作死?改到最後這個龐大的系統會不會變化這樣?

 

或者是……如這般瘋狂?

作死!的確是作死!我們來換個思路,先思考一下,既然不能把演算法給寫死在這裡面,那一定要把這個演算法給抽象一下,把實現細節從這個類裡抽離出來,獨立出來成為n個策略,就當下來講我們一共有倆個策略,一個是加法策略,一個是減法策略,他們實現的都是同一個演算法介面,接收引數為運算元a,以及被運算元b。

public interface Strategy {//演算法標準
    public int calculate(int a, int b);//運算元,被運算元
}

 下來實現加法策略、減法策略。

public class Addition implements Strategy{//實現演算法介面

    @Override
    public int calculate(int a, int b) {//加數與被加數
        return a + b;//這裡我們做加法運算
    }

}
public class Subtraction implements Strategy{//實現演算法介面

    @Override
    public int calculate(int a, int b) {//減數與被減數
        return a - b;//這裡我們做減法運算
    }

}

演算法寫好了,開始寫計算器。

 1 public class Calculator {//計算器類
 2    private Strategy strategy;//擁有某種演算法策略
 3
 4    public void setStrategy(Strategy strategy) {//接入演算法策略
 5        this.strategy = strategy;
 6    }
 7
 8    public int getResult(int a, int b){
 9        return this.strategy.calculate(a, b);//返回具體策略的結果
10    }
11 }

可以看到,計算器類裡已經把之前的具體加減演算法實現程式碼給剝離出去了,要用哪個演算法,只需要注入進來,然後獲得計算結果getResult實際上呼叫的是具體演算法的calculate,我們來看怎樣使用這個計算器。

 1 public class Client {
 2    public static void main(String[] args) {
 3        Calculator calculator = new Calculator();//例項化計算器
 4        calculator.setStrategy(new Addition());//接入加法實現
 5        int result = calculator.getResult(1, 1);//計算!
 6        System.out.println(result);//得到的是加法結果2
 7
 8        calculator.setStrategy(new Subtraction());//再次接入減法實現
 9        result = calculator.getResult(1, 1);//計算!
10        System.out.println(result);//得到的是減法結果0
11
12    }
13 }

註釋已經寫得非常明白了,相信大家都看懂了吧。那麼我們這個計算器可以說是具有演算法策略擴充套件性的,以後要有新的演算法是不需要再更改任何現有程式碼的,只需要新寫一個演算法比如乘法Multiplication,並實現calculate方法,接下來要做的只是組裝上去便可以使用了。

計算器可以搞策略,那計算機呢?還記得我們在《設計模式是什麼鬼(初探)》中舉的計算機例子吧?很顯然是同樣是策略模式,大家可以自行寫碼試煉。

從以上的幾個例子可以看出,我們的策略模式獲得了極大的應用,策略實現類已經成為獨立於宿主之外的模組,即插即用。可以組合成為一個整體,又可以分拆獨立,可以發生關聯,但絕不耦合,既對立又統一,這是唯物辯證法的絕佳體現。