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

前言
今天我們來分享另一款設計模式,相比于前面的設計模式,這種設計模式,顯得更加簡單,只有兩個類,一個是模板方法抽象類,一個是基層實現(xiàn)類。
它更像是一種自上而下的模式,有些類似于公司決策,由高層指定相關流程,由下層負責具體細則實現(xiàn),這種設計模式的好處是,當具體細則發(fā)生變更時,只需要改動具體實現(xiàn)的細則即可,而上層流程是不需要發(fā)生變化的,同樣的,如果上層流程發(fā)生變動,只需要調(diào)整生詞流程執(zhí)行過程即可,而不需要底層做任何更改,這樣就可以有效實現(xiàn)上層業(yè)務和底層實現(xiàn)之間的有效解耦,是不是很有效呢?
所以說,模板方法模式本質(zhì)上就是對IPO的代碼實現(xiàn)而已,由高層確定I/O標準,并指定具體實施的步驟(process),由底層負責具體實現(xiàn)細則,下面我們就來看下具體實現(xiàn)過程。
模板方法
模板方法模式在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。

要點
模板方法的抽象類可以定義具體方法、抽象方法和鉤子,其中抽象方法由子類實現(xiàn) 鉤子是一種方法,它在抽象類中不做事,或者只做默認的事情,子類可以選擇要不要覆蓋它 為了防止子類改變模板方法中的算法,可以將模板方法聲明為 final好萊塢原則(別找我,我會找你)告訴我們,將決策權放在高層模板中,以便于決定如何以及何時調(diào)用低層模塊
示例
下面我們就來通過日常生活中的一個示例來說明下模板方法的應用場景。這是我們針對經(jīng)常玩的兩款游戲做的一個模擬,希望通過這個示例,能夠幫助大家認識和理解模板方法。
模板方法抽象類
首先我們定義了一個抽象類,這是一個市面上所有游戲都會有的一個主體流程:資源初始化、開始游戲、游戲結束,同時定義了一個不可以被覆寫的方法(final修飾的方法子類是無法覆寫的),這樣的好處是,抽象類的提供方(上層架構)可以控制流程的執(zhí)行順序:
public?abstract?class?GameAbstract?{
????/**
?????*?初始化操作
?????*/
????abstract?void?initialize();
????/**
?????*?開始游戲
?????*/
????abstract?void?startPlay();
????/**
?????*?游戲結束
?????*/
????abstract?void?endPlay();
????/**
?????*?模板
?????*/
????public?final?void?play(){
????????//初始化游戲
????????initialize();
????????//開始游戲
????????startPlay();
????????//結束游戲
????????endPlay();
????}
}
基層實現(xiàn)
這里就是基層的實現(xiàn)(也就是服務提供方),下面是對王者榮耀這塊游戲做的模擬:
public?class?GloryOfKingsGame?extends?GameAbstract{
????@Override
????public?void?initialize()?{
????????System.out.println("=================游戲初始化==================");
????????System.out.println("初始化游戲數(shù)據(jù)");
????????System.out.println("等待確認");
????????System.out.println("加載游戲資源");
????}
????@Override
????public?void?startPlay()?{
????????System.out.println("=================開始游戲==================");
????????System.out.println("敵人還有五秒到達戰(zhàn)場……");
????????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("初始化游戲數(shù)據(jù)");
????????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("勝利");
????}
}
運行結果:

好了,示例就展示這么多,因為整體內(nèi)容也確實不難。不過,想必大家也已經(jīng)從上面的示例中理解了模板方法的設計模式,以及它的應用場景。
對比
策略模式和模板方法模式都是封裝算法,前者用了組合方式,而后者用了繼承方式 工廠方法是模板方法的一種特殊版本
總結
模板方法設計模式的核心是,由上層控制流程,下層負責具體細則實現(xiàn)。而且從示例中我們也可以很清楚地看到,上層定義了一個不可覆寫的方法來控制業(yè)務執(zhí)行流程,同時暴露了三個子類必須要實現(xiàn)的抽象方法,這樣就既可以實現(xiàn)上層和下層之間有效解耦,同時還能確保上層可以控制下層業(yè)務執(zhí)行流程,也算是一種減少上下層代碼之間互相侵入的一種有效模式吧!
- END -