1. 程式人生 > 其它 >設計模式詳解——模板方法模式

設計模式詳解——模板方法模式

前言

今天我們來分享另一款設計模式,相比於前面的設計模式,這種設計模式,顯得更加簡單,只有兩個類,一個是模板方法抽象類,一個是基層實現類。

它更像是一種自上而下的模式,有些類似於公司決策,由高層指定相關流程,由下層負責具體細則實現,這種設計模式的好處是,當具體細則發生變更時,只需要改動具體實現的細則即可,而上層流程是不需要發生變化的,同樣的,如果上層流程發生變動,只需要調整生詞流程執行過程即可,而不需要底層做任何更改,這樣就可以有效實現上層業務和底層實現之間的有效解耦,是不是很有效呢?

所以說,模板方法模式本質上就是對IPO的程式碼實現而已,由高層確定I/O標準,並指定具體實施的步驟(process

),由底層負責具體實現細則,下面我們就來看下具體實現過程。

模板方法

模板方法模式在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。

要點

  • 模板方法的抽象類可以定義具體方法、抽象方法和鉤子,其中抽象方法由子類實現
  • 鉤子是一種方法,它在抽象類中不做事,或者只做預設的事情,子類可以選擇要不要覆蓋它
  • 為了防止子類改變模板方法中的演算法,可以將模板方法宣告為final
  • 好萊塢原則(別找我,我會找你)告訴我們,將決策權放在高層模板中,以便於決定如何以及何時呼叫低層模組

示例

下面我們就來通過日常生活中的一個示例來說明下模板方法的應用場景。這是我們針對經常玩的兩款遊戲做的一個模擬,希望通過這個示例,能夠幫助大家認識和理解模板方法。

模板方法抽象類

首先我們定義了一個抽象類,這是一個市面上所有遊戲都會有的一個主體流程:資源初始化、開始遊戲、遊戲結束,同時定義了一個不可以被覆寫的方法(final修飾的方法子類是無法覆寫的),這樣的好處是,抽象類的提供方(上層架構)可以控制流程的執行順序:

public abstract class GameAbstract {
    /**
     * 初始化操作
     */
    abstract void initialize();

    /**
     * 開始遊戲
     */
    abstract void startPlay();

    /**
     * 遊戲結束
     */
    abstract void endPlay();

    /**
     * 模板
     */
    public final void play(){

        //初始化遊戲
        initialize();

        //開始遊戲
        startPlay();

        //結束遊戲
        endPlay();
    }
}
基層實現

這裡就是基層的實現(也就是服務提供方),下面是對王者榮耀這塊遊戲做的模擬:

public class GloryOfKingsGame extends GameAbstract{
    @Override
    public void initialize() {
        System.out.println("=================遊戲初始化==================");
        System.out.println("初始化遊戲資料");
        System.out.println("等待確認");
        System.out.println("載入遊戲資源");
    }

    @Override
    public void startPlay() {
        System.out.println("=================開始遊戲==================");
        System.out.println("敵人還有五秒到達戰場……");
        System.out.println("First blood!  第一滴血");
        System.out.println("double kill!  雙殺");
        System.out.println("triple kill!  三殺");
        System.out.println("Quadro  kill! 四殺");
        System.out.println("Penta kill! 五殺");
        System.out.println("Ace! 團滅");
        System.out.println("Unstoppable! 勢不可擋");
        System.out.println("God like! 超神");
        System.out.println("Legendary! 傳奇");
        System.out.println("shut down! 終結");
    }

    @Override
    public void endPlay() {
        System.out.println("=================遊戲結束==================");
        System.out.println("victory! 贏了");
    }
}

執行結果如下:

這裡是對使命召喚進行的模擬,為了模擬這個遊戲,我還專門玩了一把。我是比較喜歡射擊類遊戲的,這款遊戲也算玩的比較多的:

public class MissionCallGame extends GameAbstract {
    @Override
    public void initialize() {
        System.out.println("=================遊戲初始化==================");
        System.out.println("初始化遊戲資料");
        System.out.println("等待確認");
        System.out.println("載入遊戲資源");
    }

    @Override
    public void startPlay() {
        System.out.println("衝鋒團隊競技!");
        System.out.println("我們領先了!");
        System.out.println("目標即將完成,請再堅持一下!");
        System.out.println("目我們贏了,一大贏,小心敵人反撲!");
    }

    @Override
    public void endPlay() {
        System.out.println("勝利");
    }
}

執行結果:

好了,示例就展示這麼多,因為整體內容也確實不難。不過,想必大家也已經從上面的示例中理解了模板方法的設計模式,以及它的應用場景。

對比

  • 策略模式和模板方法模式都是封裝演算法,前者用了組合方式,而後者用了繼承方式
  • 工廠方法是模板方法的一種特殊版本

總結

模板方法設計模式的核心是,由上層控制流程,下層負責具體細則實現。而且從示例中我們也可以很清楚地看到,上層定義了一個不可覆寫的方法來控制業務執行流程,同時暴露了三個子類必須要實現的抽象方法,這樣就既可以實現上層和下層之間有效解耦,同時還能確保上層可以控制下層業務執行流程,也算是一種減少上下層程式碼之間互相侵入的一種有效模式吧!