天天看點

政策設計模式2

一、基本定義  

         政策設計模式:“針對”一組算法,“将”每一個算法封裝到具有相同接口的獨立的類中,“進而”使它們可以互相替換。

         核心:政策實作相同接口,可以互相替換。即封裝的各個算法地位平等,它們具有相同的接口,可以互相進行替換。

政策設計模式2

二、速記

        政策設計模式的重點不是如何實作算法,而是如何組織、調用這些算法。政策設計模式讓程式的結構更加靈活,讓系統具有更好的靈活性和擴充性,降低需求變動的維護成本。

        核心:封裝地位相同的各種算法,讓它們可以動态的切換。

        優點:擴充性很好,增加算法隻需要增加一個新的政策實作。

        缺點:随着政策越來越多,維護這些的政策也很困難。

        場景:用于計算公式經常變動的業務場景,比如學生的學分GPA的計算。

        注入:在業務中提供一個政策工廠。在工廠的提供的方法中通過條件來判斷應該傳回哪一個政策,這樣業務代碼就不用變動。

三、代碼實作

        政策設計模式代碼有三個主體。

        1.持有抽象政策的引用的類

        2.抽象政策類

        3.具體政策類

        範例一:政策模式經典代碼

public class Context {
    private Stategy stategy;

    public Context(Stategy stategy) {
        this.stategy = stategy;
    }

    public int result(){
        return stategy.function();
    }
    //主函數可以視為要被調用的環境,例如Service中,或者是Controller中
    public static void main(String[] args) {
        Context context = new Context(new Stategy1());
        System.out.println(context.result());

    }
}
//抽象政策
interface Stategy{
    int function();
}
//具體三種政策實作
class Stategy1 implements  Stategy{

    @Override
    public int function() {
        return 1;
    }
}
class Stategy2 implements  Stategy{

    @Override
    public int function() {
        return 2;
    }
}
class Stategy3 implements  Stategy{

    @Override
    public int function() {
        return 3;
    }
}      

        這個例子裡面Context類持有着抽象政策的引用,由構造函數接收抽象政策實作類。Context調用的result()方法,其實就是包裹的政策的function()方法。根據具體情況,選擇不同的政策的實作類,傳遞給Context類的構造器。

        範例二:政策模式與簡單工廠模式結合

        這種方式更加适合與MVC模式。Controller代碼中不直接生成相關政策,根據前台傳遞過來的參數,交由Context類的構造函數,在Context類的内部進行選擇具體的實作類。Controller層裡面的代碼隻需要知道Context類,根本不需要知道具體的政策類。在發生需求變動的時候,我們修改的類是Context類的構造函數,修改switch()語句,是以Controller層的代碼不需要變動。代碼如下:

public class Context {
    private Stategy stategy;
    public Context(int i) {
        switch (i){
            case 1:{
                stategy = new Stategy1();
                break;
            }
            case 2:{
                stategy = new Stategy2();
                break;
            }
            case 3: {
                stategy = new Stategy3();
                break;
            }
            default:{
                stategy = new Stategy1();
            }
        }

    }

    public int result(){
        return stategy.function();
    }

    //此主函數可以看作是要實際應用的環境,比如某個Controller中
    public static void main(String[] args) {
        Context context = new Context(3);//這個構造函數的參數由前端傳遞過來
        System.out.println("結果是:"+context.result());

    }
}
//政策
interface Stategy{
    int function();
}
//具體實作三種
class Stategy1 implements  Stategy{

    @Override
    public int function() {
        return 1;
    }
}
class Stategy2 implements  Stategy{

    @Override
    public int function() {
        return 2;
    }
}
class Stategy3 implements  Stategy{

    @Override
    public int function() {
        return 3;
    }
}      

        上述代碼可以看到,我們的主函數中,隻有Context類的代碼,沒有出現具體的政策類。調用Context的result()方法,實際上就是包裹調用政策類的function()方法。這個時候,如果出現需求變動,我們Controller層的代碼是不需要變動的,修改的是Context類中的switch()語句。

        有同僚說政策模式的好處之一就是可以避免 if - else 語句,我是不贊成的,因為不管怎麼說,政策模式是根據不同的情況選擇不同的政策,那麼這個過程必然會有 條件選擇語句。if - else 語句也好,swicth語句也好,條件語句經過判斷,選擇出具體的實作類,是以它們在政策模式中是不可避免的。

四、優缺點

        優點:由于政策模式的擴充性與靈活性,代碼變得便于維護。在實際中,從前端接收一個參數,然後調用簡單工廠的構造函數,在簡單工廠内部建立這個政策的執行個體對象,調用簡單工廠的方法傳回結果即可。代碼可參考第二個例子。

        擴充性展現在,當需求發生變動的時候,我們可以添加新的政策實作類,不用修改已有的政策類。

        靈活性展現在,我們可以根據需求,切換我們的政策類。

        缺點:政策模式因為需要将每一個政策都封裝成具有相同接口的獨立的類,如果目前系統中政策很多,無異于增加了代碼開發的量。另外,在調用這些政策的時候,需要對每一個政策都要了解,增加了系統的複雜性。

刻意練習

        (1)政策設計模式的核心。

        (2)政策設計模式的優點。

        (3)政策設計模式的缺點。

        (4)使用場景。

        (5)類圖

        (6)政策類怎麼注入到業務中

分割線--------------------------------------------------------------------------------------------

下一篇:工廠設計模式3