Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> java/android 設計模式學習筆記(22)---模板方法模式

java/android 設計模式學習筆記(22)---模板方法模式

編輯:關於Android編程

這篇博客我們來介紹一下模板方法模式(Template Method Pattern),也是行為型設計模式之一。在面向對象開發過程中,通常會遇到這樣的一個問題,我們知道一個算法所需的關鍵步驟,並確定了這些步驟的執行順序,但是,某些步驟的具體實現是未知的,或者說某些步驟的實現是會隨著環境的變化而改變的,這時候我們就可以創建一個算法的模板,將算法定義成一組步驟,其中的任何步驟都可以是抽象的,由子類負責實現,這可以確保算法的結構保持不變,同時由子類提供部分實現。

特點

定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結構即可重新定義該算法的某些特定步驟。
  模板方法模式的使用場景:

多個子類有共有的方法,並且邏輯基本相同時;重要、復雜的算法,可以把核心算法設計成模板方法,周邊相關細節功能則由各個子類實現;重構時,模板方法模式是一個經常使用的模式,把相同的代碼抽取到父類中,然後通過鉤子函數約束其行為。

 

UML類圖

這裡寫圖片描述
這裡涉及到兩個角色:

抽象模板(Abstract Template)角色有如下責任:定義了一個或多個抽象操作,以便讓子類實現,這些抽象操作叫做基本操作,它們是一個頂級邏輯的組成步驟。定義並實現了一個模板方法,這個模板方法一般是一個具體方法,它給出了一個頂級邏輯的骨架,而邏輯的組成步驟在相應的抽象操作中,推遲到子類實現,頂級邏輯也有可能調用一些具體方法。具體模板(Concrete Template)角色有如下責任:實現父類所定義的一個或多個抽象方法,它們是一個頂級邏輯的組成步驟。每一個抽象模板角色都可以有任意多個具體模板角色與之對應,而每一個具體模板角色都可以給出這些抽象方法(也就是頂級邏輯的組成步驟)的不同實現,從而使得頂級邏輯的實現各不相同。我們可以寫出模板方法模式的通用代碼:
AbstractTemplate.class

 

public abstract class AbstractTemplate {
    /**
     * 模板方法
     */
    public void templateMethod(){
        //調用基本方法
        abstractMethod();
        hookMethod();
        concreteMethod();
    }
    /**
     * 基本方法的聲明(由子類實現)
     */
    protected abstract void abstractMethod();
    /**
     * 基本方法(空方法)
     */
    protected void hookMethod(){
        System.out.print("AbstractTemplate hookMethod\n");
    }
    /**
     * 基本方法(已經實現)
     */
    private final void concreteMethod(){
        System.out.print("AbstractTemplate concreteMethod\n");
    }

    public static void main(String[] args) {
        AbstractTemplate templateA = new ConcreteTemplateA();
        templateA.templateMethod();

        AbstractTemplate templateB = new ConcreteTemplateB();
        templateB.templateMethod();
    }
}

ConcreteTemplateA.class

public class ConcreteTemplateA extends AbstractTemplate{
    @Override
    protected void abstractMethod() {
        System.out.print("ConcreteTemplateA abstractMethod\n");
    }
}

ConcreteTemplateB.class

public class ConcreteTemplateB extends AbstractTemplate{
    @Override
    protected void abstractMethod() {
        System.out.print("ConcreteTemplateB abstractMethod\n");
    }

    @Override
    protected void hookMethod() {
        System.out.print("ConcreteTemplateB hookMethod\n");
    }
}

最後運行的結果:

ConcreteTemplateA abstractMethod
AbstractTemplate hookMethod
AbstractTemplate concreteMethod
ConcreteTemplateB abstractMethod
ConcreteTemplateB hookMethod
AbstractTemplate concreteMethod

基類定義了一系列的步驟,然後子類按照這個步驟去實現,注意到兩個方法,一個是 abstractMethod 和 hookMethod ,這兩個方法的定位是不一樣的, abstractMethod() 方法所代表的就是強制子類實現的剩余邏輯,而 hookMethod() 方法是可選擇實現的邏輯,不是必須實現的。

示例與源碼

Android 中使用模板方法模式最典型的例子就是 AsyncTask 和 Activity 的生命周期函數,這兩個類基本都會有接觸到,感興趣的可以深入去了解。
  我們這裡以一個游戲的初始化為例子:
Game .class

/**
 * An abstract class that is common to several games in
 * which players play against the others, but only one is
 * playing at a given time.
 */
abstract class Game {
    /* Hook methods. Concrete implementation may differ in each subclass*/
    protected int playersCount;
    abstract void initializeGame();
    abstract void makePlay(int player);
    abstract boolean endOfGame();
    abstract void printWinner();

    /* A template method : */
    public final void playOneGame(int playersCount) {
        this.playersCount = playersCount;
        initializeGame();
        int j = 0;
        while (!endOfGame()) {
            makePlay(j);
            j = (j + 1) % playersCount;
        }
        printWinner();
    }
}

Monopoly.class

//大富翁
class Monopoly extends Game {

    /* Implementation of necessary concrete methods */
    void initializeGame() {
        System.out.print("Monopoly initializeGame\n");
    }
    void makePlay(int player) {
        return player > 4 ? 4 : palyer;
    }
    boolean endOfGame() {
        System.out.print("Monopoly endOfGame\n");
    }
    void printWinner() {
        System.out.print("Monopoly printWinner\n");
    }
    //....
}

Chess.class

//象棋
class Chess extends Game {

    /* Implementation of necessary concrete methods */
    void initializeGame() {
        System.out.print("Chess initializeGame\n");
    }
    void makePlay(int player) {
        return 2;
    }
    boolean endOfGame() {
        System.out.print("Chess endOfGame\n");
    }
    void printWinner() {
        System.out.print("Chess printWinner\n");
    }
    //.....
}

根據游戲的不同,不同的方法會有不同的執行結果,但是每個游戲的執行步驟是一樣的。

總結

模板方法模式用四個字概括就是:流程封裝。也就是把某個固定的流程封裝到一個 final 函數中,並且讓子類能夠定制這個流程中的某些或者所有步驟,這就要求父類提取公用的代碼,提升代碼的復用率,同時也帶來了更好的可封裝性。
  模板方法模式的優點:

封裝不變部分,擴展可變部分;提取公共部分代碼,便於維護。缺點:模板方法會帶來代碼閱讀的難度,加大理解的難度,而且由於父類將步驟固定,所以有時候會增加擴展的難度。

 

源碼下載

https://github.com/zhaozepeng/Design-Patterns/tree/master/TemplatePattern

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved