天天看點

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

版權聲明:尊重部落客原創文章,轉載請注明出處哦~http://blog.csdn.net/eson_15/article/details/51323902

        這一節主要來學習一下設計模式中的模闆方法模式。我們先來看一個例子:假如現在老闆讓你做一個汽車的模型,要求隻要完成基本功能即可,不考慮擴充性,那你會怎麼做呢?我們首先會根據經驗設計一個類圖:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

       由這個類圖可知,非常簡單的實作了悍馬車,該車有兩個型号h1和h2。那現在我們開始實作這兩個型号的悍馬車,首先我們得把抽象類寫好,然後兩個不同的模型實作類通過簡單的繼承就可以實作要求。首先看看抽象類的代碼:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

public abstract class hummermodel {  

    public abstract void start(); //發動  

    public abstract void stop();  //停止  

    public abstract void alarm(); //鳴笛  

    public abstract void engineboom(); //轟鳴  

    public abstract void run(); //車總歸要跑  

}  

        簡單到不行,下面我們來實作兩個悍馬的模型:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

//悍馬h1  

public class hummerh1 implements hummermodel {  

    @override  

    public void start() {  

        system.out.println("h1發動……");  

    }  

    public void stop() {  

        system.out.println("h1停止……");  

    public void alarm() {  

        system.out.println("h1鳴笛……");  

    public void engineboom() {  

        system.out.println("h1轟鳴……");  

    public void run() {  

        this.start();  

        this.engineboom();  

        this.alarm();  

        this.stop();  

//悍馬h2  

public class hummerh2 implements hummermodel {  

        system.out.println("h2發動……");  

        system.out.println("h2停止……");  

        system.out.println("h2鳴笛……");  

        system.out.println("h2轟鳴……");  

        很明顯,已經發現代碼有點問題了,兩個悍馬的run方法完全相同。是以這個run方法應該出現在抽象類中,不應該在實作類中,抽象是所有子類的共性封裝。是以我們修改一下抽象類:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

    public void run() { //車總歸要跑  

        這樣兩個實作類就不用實作run方法了,可以直接拿來用。其實,這就是模闆方法模式。

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充
【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

public abstract class abstractclass {  

    //基本方法  

    protected abstract void dosomething();  

    protected abstract void doanything();  

    //模闆方法  

    public void templatemethod() {  

        //調用基本方法,完成相關的邏輯  

        this.doanything();  

        this.dosomething();  

        具體實作類就不寫了……

      優點:

        1)封裝不變部分,擴充可變部分:把認為不變部分的算法封裝到父類實作,可變部分則可以通過繼承來實作,很容易擴充。

        2)提取公共部分代碼,便于維護:上面悍馬的例子就是個很好的解釋。

        3)行為由父類控制,由子類實作。

      缺點:

        模闆方法模式颠倒了我們平常的設計習慣:抽象類負責聲明最抽象、最一般的事物屬性和方法,實作類實作具體的事物屬性和方法。在複雜的項目中可能會帶來代碼閱讀的難度。

        還是上面那個悍馬的例子,現在老闆說這車幹嘛跑起來就要鳴笛,太吵了,難道不是應該讓使用者決定它是否要鳴笛麼?好像确實是這樣的……那好辦,我們可以修改一下抽象模闆類中的方法:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

    protected abstract void start(); //發動  

    protected abstract void stop();  //停止  

    protected abstract void alarm(); //鳴笛  

    protected abstract void engineboom(); //轟鳴  

    final public void run() { //車總歸要跑  

        if(this.isalarm()) {//想讓它叫就叫,不想就不叫        

            this.alarm();  

        }  

    protected boolean isalarm() { //我們加了一個判斷方法,預設傳回true  

        return true;  

       我們在模闆類中增加了一個判斷方法來判斷是否要鳴笛,現在就好辦了,具體實作類隻要重寫這個方法就可以做到人為控制是否要鳴笛了,下面我們來看一下實作類:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

public class hummerh1 extends hummermodel {  

    private boolean alarmflag = true; //判斷标記  

    protected boolean isalarm() { //覆寫isalarm方法,傳回判斷标記  

        return this.alarmflag;  

    public void setalarm(boolean isalarm) { //設定判斷标記  

        this.alarmflag = isalarm;  

        這個實作很好,我們在實作類中定義一個判斷标記,然後對外提供一個public接口setalarm來讓外界設定這個判斷标記,這就像是開關一樣,想讓它ture和false都行。這個isalarm方法俗稱鈎子方法。有了鈎子方法的模闆方法模式才算完美,大家可以想象一下,由子類的一個方法傳回值決定公共部分的執行結果,這個是很有吸引力的。我們來測試一下:

【java設計模式】之 模闆方法(Template Method)模式 1. 模闆方法的一個執行個體 2. 模闆方法模式的定義 3. 模闆方法模式的優缺點 4. 模闆方法模式的擴充

public class test {  

    public static void main(string[] args) throws ioexception {  

        system.out.println("----h1型悍馬----");  

        system.out.println("是否需要喇叭聲響? 0-不需要  1-需要");  

        string type = new bufferedreader(new inputstreamreader(system.in)).readline();  

        hummerh1 h1 = new hummerh1();  

        if(type.equals("0")) {  

            h1.setalarm(false);  

        h1.run();  

        當輸入不同的指令後,就會決定不同的動作:即要不要鳴笛,至此,這個模闆方法模式就介紹完了。

_____________________________________________________________________________________________________________________________________________________

-----樂于分享,共同進步!