編輯:關於Android編程
這篇博客我們來介紹一下模板方法模式(Template Method Pattern),也是行為型設計模式之一。在面向對象開發過程中,通常會遇到這樣的一個問題,我們知道一個算法所需的關鍵步驟,並確定了這些步驟的執行順序,但是,某些步驟的具體實現是未知的,或者說某些步驟的實現是會隨著環境的變化而改變的,這時候我們就可以創建一個算法的模板,將算法定義成一組步驟,其中的任何步驟都可以是抽象的,由子類負責實現,這可以確保算法的結構保持不變,同時由子類提供部分實現。
定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結構即可重新定義該算法的某些特定步驟。
模板方法模式的使用場景:
這裡涉及到兩個角色:
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
連續的輸入事件可能會產生一定的手勢操作,例如滑動手勢和捏合手勢。在Chromium中,網頁的輸入事件是在Browser進程中捕捉的。Browser進程捕獲輸入事件之後,會
Android中的消息處理機制大量依賴於Handler。每個Handler都有對應的Looper,用於不斷地從對應的MessageQueue中取出消息處理。 一直以來,覺
問題背景:app在上傳圖片時,同時傳遞參數,支持傳遞多個圖片。本文中的環境默認已經配好了服務器的CodeIgniter框架。事實上不使用這個框架也是可以的。 一,服務器部
一,系統啟動Android設備的開機流程總得來分可以分為三部分:加載引導程序引導程序bootloader是開機運行的第一個小程序,因此它是針對特定的主板與芯片的。boot