設計模式之模板方法模式(三分鐘學會一個設計模式)

王若伊_恩赐解脱發表於2024-09-07

模板方法模式(Template Method Pattern)也稱之為模板模式(Template Pattern),是設計模式中最簡單的模式之一。

先來看定義:
定義一個操作中演算法的骨架(模板),將一些步驟延遲到子類中,模板方法使得子類可以不改變演算法的結構即可重新定義演算法某些特定的步驟。
這個定義還是有一些晦澀,我的理解是這樣的:(防盜連線:本文首發自http://www.cnblogs.com/jilodream/ )
在父類中我們可以定義一塊業務的整體實現過程,但是針對某些步驟的具體實現邏輯,我們可以暫時先只定義一個抽象方法,在未來定義子類的過程中,實現/重寫該方法。
這個模式主要是為了解決,很多場景中,我們並不知道未來實際使用中,具體需要怎麼實現,甚至會出現多個具體實現,針對此,我們可以先定義父類中已經明確的業務。
大致的呼叫結構如下:

它是物件導向的23種設計模式中的一種,屬於行為模式的範圍。
來看示例程式碼:

音樂播放器抽象類

 1 package com.example.demo.learn.pattern.behavior.templatemethod;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public abstract class AbstractMusicPlayer {
10     public void startUp() {
11         showFrame();
12         doCustomizedOpt();
13     }
14 
15     protected abstract void playWelcomeMsg();
16 
17     protected void showFrame() {
18         showMainFrame();
19         playWelcomeMsg();
20     }
21 
22     protected abstract void doCustomizedOpt();
23 
24 
25     protected abstract void showMainFrame();
26 }

酷貓播放器

 1 package com.example.demo.learn.pattern.behavior.templatemethod;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class CoolCatPlayer extends AbstractMusicPlayer{
10     @Override
11     protected void playWelcomeMsg() {
12       log.warn("hi man");
13     }
14 
15     @Override
16     protected void doCustomizedOpt() {
17         log.warn("您有一份價值99元的免費禮品待領取,快點選下方連結");
18     }
19 
20     @Override
21     protected void showMainFrame() {
22         log.warn("開啟酷貓音樂主介面");
23     }
24 }

酷他音樂盒

 1 package com.example.demo.learn.pattern.behavior.templatemethod;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class CoolHePlayer extends AbstractMusicPlayer {
10     @Override
11     protected void playWelcomeMsg() {
12         log.warn("歡迎來到酷他音樂盒");
13     }
14 
15     @Override
16     protected void doCustomizedOpt() {
17         log.warn("一刀999,和兄弟一起戰個痛快");
18     }
19 
20     @Override
21     protected void showMainFrame() {
22         log.warn("開啟酷他音樂盒主介面");
23     }
24 }

執行主類

 1 package com.example.demo.learn.pattern.behavior.templatemethod;
 2 
 3 /**
 4  * @discription
 5  */
 6 
 7 public class PatternMain {
 8     public static void main(String[] args) {
 9         AbstractMusicPlayer coolCat = new CoolCatPlayer();
10         coolCat.startUp();
11 
12         AbstractMusicPlayer coolHe = new CoolHePlayer();
13         coolHe.startUp();
14     }
15 }

輸出如下

15:38:12.515 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolCatPlayer - 開啟酷貓音樂主介面
15:38:12.518 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolCatPlayer - hi man
15:38:12.518 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolCatPlayer - 您有一份價值99元的免費禮品待領取,快點選下方連結
15:38:12.518 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolHePlayer - 開啟酷他音樂盒主介面
15:38:12.518 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolHePlayer - 歡迎來到酷他音樂盒
15:38:12.518 [main] WARN com.example.demo.learn.pattern.behavior.templatemethod.CoolHePlayer - 一刀999,和兄弟一起戰個痛快

我們定義了一個播放器的類,並且約定了播放器啟動時,我們需要具體做的業務:

類圖

步驟1、開啟主介面

步驟2、做一些定製的使用者操作
但是有多個播放器(如酷貓音樂、酷他音樂盒),他們的主介面和使用者定製操作都各有不同,因此我們可以先只定義以上操作的抽象方法,對於具體操作的實現留給子類完成即可。

模板方法核心的步驟就是2點:
父類中定義骨架(模板),組織各種定義好的抽象方法
子類根據實際業務實現抽象方法

相關文章