1. 程式人生 > >設計模式之模板方法模式實戰解析

設計模式之模板方法模式實戰解析

本文微信公眾號「AndroidTraveler」首發。

背景

最近在看《設計模式之禪》,為了能夠更加深入的理解設計模式,達到學以致用。
這邊記錄一下自己的一些感受和看法,並結合具體程式碼實戰來進行說明。

模板方法模式

但凡和設計模式掛上鉤,我們總是會覺得「高不可攀」。
然而實際上,設計模式是基於大量實際程式碼的經驗總結,它來自於實際的程式碼。
與其說「高不可攀」,其實它反而是比較「接地氣」。
而模板方法模式相信你看完本篇文章之後,會發現,原來這就是模板方法模式,然後就去看你之前的程式碼了。

小例子初識模板方法模式

理解設計模式最好的方法就是通過專案開發中的實際場景來說明。

大家做 Android 開發的時候寫 Activity 應該都會看到下面類似程式碼吧?

private void getIntents() {
    // 從 Intent 獲取傳遞過來的一些引數,設定到屬性中
}

private void findViewById() {
    // 通過 findViewById 來初始化各個元件
}

private void setViews() {
    // 給元件設定監聽或者初始狀態
}

假設我每個介面都這樣寫,那麼重複程式碼太多了,很沒必要。
雖然每個方法具體的邏輯不一樣,但是都有這些操作。

這個時候我們第一個想法就是繼承,抽取出一個 BaseActivity。
然後將這些通用程式碼都放到了 BaseActivity 裡面,子類再來覆寫就可以了。

但是還有一個問題,那就是,我每次都需要寫下面程式碼:

getIntents();
findViewById();
setViews();

尤其是通用程式碼多的時候,有時候手誤可能導致某些介面這三個方法呼叫順序還不一樣。
那怎麼辦呢?我們可以抽取出一個方法,這個方法代表了這三個方法統一的呼叫順序,這樣就不怕手誤寫錯了。
而這個方法就是我們的模板方法。

public abstract class BaseActivity extends Activity {
    /**
     * 從 Intent 獲取傳遞過來的一些引數,設定到屬性中
     */
    protected abstract void getIntents();

    /**
     * 通過 findViewById 來初始化各個元件
     */
    protected abstract void findViewById();

    /**
     * 給元件設定監聽或者初始狀態
     */
    protected abstract void setViews();

    /**
     * 模板方法
     */
    final public void init() {
        getIntents();
        findViewById();
        setViews();
    }
}

這樣我後面的 Activity 都可以繼承這個 BaseActivity,然後只需要呼叫 init 方法即可。
至於不同的 Activity 的邏輯我再在三個方法裡面各自實現即可。

鉤子方法

一聽到這個詞,是不是覺得有點「高大上」,似乎很 NB?
然而,聽完我後面的講述,你內心估計

我們上面的方法裡面,並不是所有的 Activity 都有其他 Activity 傳遞資料過來的,因此 getIntents 這個方法不一定所有子類都要呼叫。
這個時候我們可以提供一個鉤子方法,改動部分程式碼如下:

/**
 * 模板方法
 */
final public void init() {
    if (isGetIntents()) {
        getIntents();
    }
    findViewById();
    setViews();
}

/**
 * 鉤子方法,是否需要設定資料,預設為 true
 * @return
 */
protected boolean isGetIntents() {
    return true;
}

可以看到,通過鉤子方法,當我們預設需要獲取資料時,什麼都不用改動,如果我們不需要獲取資料,只需要覆寫我們的鉤子方法 isGetIntents 並返回 false 即可。

好了,有了初步的印象之後,接下來就正式的加深瞭解吧。

定義

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
定義一個操作中的演算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

簡單的說就是父類定義了一個模板方法,在這個模板方法裡面有一些特定的步驟。具體的步驟實現留給子類去處理。

父類的模板方法保持了各個子類的共性,模板方法裡面的步驟使得每個子類都有自己的個性。

通用程式碼實現

父類:

public abstract class AbstractPatternClass {
    /**
     * 基本方法,模板方法裡面呼叫
     */
    protected abstract void firstModule();
    /**
     * 基本方法,模板方法裡面呼叫
     */
    protected abstract void secondModule();

    /**
     * 模板方法,多個基本方法組合
     */
    final public void templateMethod() {
        firstModule();
        secondModule();
    }
}

具體子類:

public class ConcreteClass extends AbstractPatternClass {
    @Override
    protected void firstModule() {
        // TODO 子類實現自己的邏輯
    }

    @Override
    protected void secondModule() {
        // TODO 子類實現自己的邏輯
    }
}

場景使用類:

public class PatternTest {
    public static void main(String[] args) {
        AbstractPatternClass abstractPatternClass = new ConcreteClass();
        // 呼叫模板方法
        abstractPatternClass.templateMethod();
    }
}

鉤子方法我們上面已經說過了,相信聰明的你知道如何使用,這裡就不再贅述了。

注意點

父類中的基本方法儘量設計為 protected 型別,符合迪米特法則。
父類中的模板方法一般設定為 final,不允許子類覆寫。這樣的目的一個是為了避免子類惡意操作,一個是為了模板的共性。

應用

當你在寫程式碼經常用到複製和貼上快捷鍵時,你就要考慮是不是可以進行抽取。
當你修改一個地方的時候,發現其他地方也要連帶修改,也需要考慮一下。
多個子類有公共方法,並且邏輯基本相同。
複雜的一些演算法之類的,可以讓子類通過基本方法傳遞一些引數,核心邏輯放在模板方法裡面。
重構專案的時候,也可以考慮一下把相同程式碼抽取到父類,通過鉤子方法定製化模板。

結語

最後一點就是注意不要濫用設計模式,不要為了設計而設計

參考資料:
設計模式之禪(第2版)

相關推薦

設計模式模板方法模式實戰解析

本文微信公眾號「AndroidTraveler」首發。 背景 最近在看《設計模式之禪》,為了能夠更加深入的理解設計模式,達到學以致用。 這邊記錄一下自己的一些感受和看法,並結合具體程式碼實戰來進行說明。 模板方法模式 但凡和設計模式掛上鉤,我們總是會覺得「高不可攀」。 然而實際上,設計模式是基於大量實際程式碼

Head First設計模式模板方法模式

names 去除 缺點 ide 個數 write ima 父類 public 一、定義 在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中,使得子類可以不改變算法結構的情況下,重定義該算法中的某些特定步驟。 比較通俗的說法,子類決定如何實現算法中的某些步驟,比如兩

java設計模式模板方法模式

java 設計模式宋丹丹姐的一個小品,說把大象放入冰箱分為幾步驟,三步、第一步:把冰箱門打開,第二步:把大象裝進去,第三步:把冰箱門關上。就是這樣的一個小品,可以說是其實簡化的一個模板方法。把雞蛋裝進冰箱分為幾步,同樣也是這個道理。模板方法模式概念:把一些共同的行為抽象出來,作為父類公共使用,一些具體的步驟

23種設計模式模板方法模式

技術分享 cnblogs ati strac void package com rim div 模板方法模式(TemplateMethod):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

設計模式模板方法模式

nbsp outline 依次 print 繪畫 false 鉤子方法 註意 div (文章的部分內容參考了《設計模式之禪》一書,大家也可以讀讀看,內容寫的非常好) 什麽是模板方法模式 它的定義如下: 定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變

GOF23設計模式模板方法模式(template method)

評分 end 抽象方法 abs 方法調用 轉移 pri spa 應用 一、模板方法模式概述   模板方法模式是編程中經常使用的模式。它定義了一種操作中的算法架構,將某些步驟延遲到子類中實現。這樣,新的子類可以在不改變一個算法結構的前提下重新定義該算法的某些特定步驟。   (

設計模式模板方法模式(TemplateMethod)

pla AR 應用 blog public ood 操作 () eal 模板方法模式使用繼承來實現模式的功能,在基類使用一個方法來定義算法的各個步驟,這些步驟(方法)的具體實現會放到子類中,通過這樣來實現不同算法對象的算法拼合,完成該對象整體算法的實現。 作用 模板方法

設計模式的藝術 行為型模式模板方法模式

前言 生活中有許多事情可以理解成分步驟執行的東西,比如請客吃飯,無論吃什麼,一般都包含著點單,吃東西,買單幾個步驟,不論吃麵還是吃大餐,其他步驟不會變,最多變變點單,在軟體開發中,也會有類似的情況出現,我們可以有個點單的基類,然後子類裡面具體實現是吃麵還是點大餐,這就是模板方法模式,這種模式利用

JAVA設計模式模板方法模式和建造者模式

一、前期回顧 上一篇《Java 設計模式之工廠方法模式與抽象工廠模式》介紹了三種工廠模式,分別是工廠方法模式,簡單工廠方法模式,抽象工廠模式,文中詳細根據實際場景介紹了三種模式的定義,實踐,最後總結了三種方式的區別,以及各個模式的適用場景。這一篇博文我們來學習下模板方法模式和建造者模式。

每天學點設計模式---模板方法模式

模板方法模式的定義理解: 模板方法:父類中定義好演算法的的完整執行框架,子類根據自身需求實現具體的演算法步驟; 比如珍珠奶茶的製作流程,可以總結出一套固定的執行流程, 1.先準備一杯清水河一個塑料杯子 2.在準備好的塑料杯中新增珍珠奶茶需要的原

Android原始碼設計模式模板方法模式

在面向物件開發中,通常會遇到這樣一個問題,我們知道一個演算法所需的關鍵步驟,並確定了這些步驟的執行順序,但是某些步驟的具體實現是未知的,或者說某些步驟的實現是會隨著環境的變化而改變的,例如,執行程式的流程大致如下: 1.檢查程式碼的正確性; 2.連結相關的類庫; 3.編譯相關的程式碼;

設計模式模板方法模式(行為型)

目錄 一、模式定義 二、模式角色 三、模式分析 四、具體例子 五、模式應用場景 一、模式定義 模板方法模式就是在一個抽象類中定義一些骨架方法,然後通過類繼承的方法,將一些方法延遲到繼承類裡。模板方法模式是一種類行為型模式,是一種比較常用的方法。不屬於物件行為型模式,因為只是通過

Java設計模式模板方法模式(Template Method)

本文繼續介紹23種設計模式系列之模板方法模式。概述模板方法模式是類的行為模式。準備一個抽象類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。這就是模板方法

設計模式-模板方法模式

角色 抽象類(AbstractClass):實現了模板方法,定義了演算法的骨架。 具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的演算法 舉個例子,以準備去學校所要做的工作(prepareGotoSchool)為例,假設需要分三

面向物件設計模式---模板方法模式(Template Method Pattern)

這幾天遇到了一些事,生活中有太多的不確定性,我所能做的就是做最好的自己。爭取能把這本《大話設計模式》的讀書筆記做完吧,說真的雖然現在只是Cover到知識點,還並沒有實戰,不過我想這就是一種積累。就像之前剛閱讀完的《深入淺出MySQL》高階部分一樣,雖然蠻多還是看不懂,畢竟我不是專

設計模式模板方法模式、策略模式、命令設計模式

一、模板方法模式 模板方法模式需要開發抽象類和具體子類的設計師之間的協作。一個設計師負責給出一個演算法的輪廓和骨架,另一些設計師則負責給出這個演算法的各個邏輯步驟。代表這些具體邏輯步驟的方法稱做基本方法(primitive method);而將這些基本方法彙總起來的方法叫做

淺談java 23種設計模式模板方法模式(Template )

模板方法模式:模板方法模式是類的行為模式的一種,符合開閉原則(對擴充套件開放,對修改關閉)。父類提取子類公共方法,並提供若干抽象方法供子類實現,以減少子類中的重複程式碼,並提高可複用性。示例:1.建立一個父類bird,每天只有吃和睡才能生活,但是必須要先進行吃,然後再進行睡:

設計模式模板方法模式(Template)

           模板方法模式定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。 何時應用: 1、需要一次性實現演算法的不變部分,並

設計模式模板方法模式(Template Method)

            本來打算按照書上的講的設計模式一個一個學下來,但是讀spring原始碼的時候遇到模板方法模式,不懂,就提前先學一下。 模板方法模式就是定義一個演算法執行的骨架,而具體的演算法被延遲到子類中去實現,在spring中很多地方都使用到了模板方法模式,比如s

JAVA設計模式 模板方法模式【Template Method Pattern】

一、概述     定義一個操作中演算法的框架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。它是一種類行為型模式。 二、適用場景     適用於對一些複雜的操作/演算法進行步驟分割、抽取公共部分由抽象父類實現