1. 程式人生 > >一天一個設計模式:模板方法模式

一天一個設計模式:模板方法模式

概念:

  模板方法模式是類的行為模式,準備一個抽象類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。這就是模板方法模式的意思。

結構:

  模板方法模式中,抽象類負責定義整個的邏輯框架,而具體的邏輯步驟由具體的子類實現。具體的邏輯步驟稱作基本方法(primitive method),將基本方法彙總的方法稱為模板方法(template method)

  模板方法是頂級的行為定義,即該抽象類可以作什麼功能是由模板方法定義的,但是其中的細節則是由其子類中的基本方法實現的。

  用一句諺語表示就是:條條大路通羅馬

靜態結構圖:

  

抽象模板(Abstract Template)角色:

   定義了一個或多個抽象操作,以便讓子類實現,這些抽象操作稱為基本方法,他們是頂級邏輯的組成步驟。

  定義並實現了一個模板方法,模板方法一般是一個具體實現,它給出了一個頂級邏輯的骨架,而邏輯的組成步驟在相應的抽象操作中,推遲子類的實現,頂級邏輯也可能呼叫一些具體的方法。(不建議這樣)

具體模板(Concrete Template)角色:

  實現父類定義的一個或多個抽象方法,這些實現方法是頂級邏輯的組成步驟。

  一個抽象模板可以有多個具體模板對其實現,且其實現的細節均可不同。

程式碼:

抽象模板角色類:

public
abstract class AbstractTemplate { /** * 模板方法 */ public void templateMethod(){ //呼叫基本方法 abstractMethod(); hookMethod(); concreteMethod(); } /** * 基本方法的宣告(由子類實現) */ protected abstract void abstractMethod(); /** * 基本方法(空方法)
*/ protected void hookMethod(){} /** * 基本方法(已經實現) */ private final void concreteMethod(){ //業務相關的程式碼 } }
View Code

具體模板角色類:

public class ConcreteTemplate extends AbstractTemplate{
    //基本方法的實現
    @Override
    public void abstractMethod() {
        //業務相關的程式碼
    }
    //重寫父類的方法
    @Override
    public void hookMethod() {
        //業務相關的程式碼
    }
}
View Code

關鍵的地方在於:子類可以置換掉父類的可變部分,但是子類卻不可以改變模板方法所代表的頂級邏輯。

模板方法模式的方法:

  分為兩大類:模板方法和基本方法

  模板方法

  一個模板方法是定義在抽象類中的,把基本操作方法組合在一起形成一個總演算法或一個總行為的方法。

  一個抽象方法可以包含任意個模板方法,每個模板方法都可以呼叫任意多個具體方法。

  基本方法:

  分為三種:抽象方法(Abstract Method)、具體方法(Concrete Method)和鉤子方法(Hook Method)。

  抽象方法:一個抽象方法由抽象類宣告,由具體子類實現。在Java語言裡抽象方法以abstract關鍵字標示。

  具體方法:一個具體方法由抽象類宣告並實現,而子類並不實現或置換。
  鉤子方法:一個鉤子方法由抽象類宣告並實現,而子類會加以擴充套件。通常抽象類給出的實現是一個空實現,作為方法的預設實現。

在上面的例子中,AbstractTemplate是一個抽象類,它帶有三個方法。其中abstractMethod()是一個抽象方法,它由抽象類宣告為抽象方法,並由子類實現;hookMethod()是一個鉤子方法,它由抽象類宣告並提供預設實現,並且由子類置換掉。concreteMethod()是一個具體方法,它由抽象類宣告並實現。

  預設鉤子方法:

  一個鉤子方法常常由抽象類給出一個空實現,作為此方法的預設實現,這種空的鉤子方法叫做"Do Nothing Hook"。

  命名規則:

  鉤子方法的名字應該以do開始。

模板方法模式在Servlet中的應用:

  使用過Servlet的人都清楚,除了要在web.xml做相應的配置外,還需繼承一個叫HttpServlet的抽象類。HttpService類提供了一個service()方法,這個方法呼叫七個do方法中的一個或幾個,完成對客戶端呼叫的響應。這些do方法需要由HttpServlet的具體子類提供,因此這是典型的模板方法模式。下面是service()方法的原始碼:

    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);        
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }
View Code

如圖所示,我們也可以對servlet的方法進行重寫。

  從上面的例子可以看出這是一個典型的模板方法模式。

  HttpServlet擔任抽象模板角色

    模板方法:由service()方法擔任。

    基本方法:由doPost()、doGet()等方法擔任。

  TestServlet擔任具體模板角色

TestServlet置換掉了父類HttpServlet中七個基本方法中的其中兩個,分別是doGet()和doPost()。

相關推薦

天一設計模式模板方法模式

概念:   模板方法模式是類的行為模式,準備一個抽象類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。這就是模板方法模式的意思。 結構:   模板方法模式中,抽象類負責定義整個的邏輯框架,

C#設計模式之行為類模式模板方法模式

frame 應該 ocp 方式 src 代碼復用 操作 優缺點 sse 定義(Template Method) 定義一個操作中算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。 啟示 組裝電腦一般包含三個部分,主機、顯示

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

設計模式 模板方法模式 模板方法 模板方法模式 定義:模板方法模式在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。模板方法就是一個固定步驟的“算法”骨架方法。這個算法的可變部分通過繼承,在子類中重載實現。這樣就可以

設計模式模板方法模式-template method

定義一個操作中的演算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重新定義該演算法的某些特定步驟 在抽象父類中,可以定義多種不同型別的方法,如下: 呼叫基本

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

/** * 模板方法模式。 * 模板方法模式在一個方法中定義演算法的骨架,而將一些步驟延遲到子類中。 * 模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。 * @author Bright Lee */ public class TemplateMeth

天一設計模式工廠方法模式

工廠方法模式:   定義一個生產產品物件的工廠介面,將建立生產產品的工廠的工作交給子類實現。   隨著實際需要的工廠數量增加,簡單工廠模式體積會迅速膨脹,程式碼迅速臃腫嚴重。  補充:工廠方法模式是針對一類產品的工廠   所以為了程式碼的可閱讀下與可維護性,也做到不同的業務有一定的隔離,將工廠的功能抽象出來成

天一設計模式抽象方法模式

為什麼引入抽象工廠模式? 或者說抽象工廠模式與工廠方法模式的區別? 工廠方法模式針對的是一類產品的等級結構,而抽象工廠模式針對的是多個產品等級結構(一個產品族)。 引入概念:產品族與產品等級 產品族:指在不同的產品等級結構中,功能相關聯的產品組成的家族。產品等級:同類產品的不同產品區分。 抽象工廠的作用:

天一設計模式介面卡模式

概念:   介面卡模式是把一個類的介面變成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。 用途:   就像插頭轉換器,之前入了switch港版,插頭是英式的,還好附贈一個插頭轉換器,介面卡就相當於這個轉換器。 種類:   分為類的介面卡與物件的介面卡兩種

天一設計模式裝飾者模式

概念:   裝飾者模式又稱為包裝(wrapper)模式。裝飾者模式對客戶端透明的方式擴充套件物件的功能,是繼承關係的一個替代方案。 結構:   裝飾者模式以透明的方式給一個物件附加上更多的責任,換而言之,客戶端並不會覺得物件在裝飾前後有什麼不同,裝飾者模式可以在不使用創造更多子類的情況下,將物件的功能拓展。

天一設計模式策略模式

概念:   策略模式屬於物件的行為模式,其用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響客戶端的情況下變化。 結構: 環境(Context)角色:持有一個Strategy的引用。 抽象策略(Strategy)角色:這是一個抽象角色

天一設計模式建造模式

概念:   建造模式是物件的建立模式,建造模式可以將一個產品的內部表象(個人理解,可以稱為元件)與產品的生產分割開來,從而可以使一個建造過程生產出來具有不同內部表象的產品物件。 概念: 產品的內部表象:   產品不同組成成分構成(元件)這些零件可以是物件,也可以是非物件,稱為內部表象(internal re

天一設計模式單例模式

概念:   作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化,並向整個系統提供這個例項。 特點:   1.單例類只能有一個例項   2.單例類必須建立自己的唯一例項   3.單例類必須給其他所有物件提供這一例項。 餓漢式單例類 public class EagerSingleton {

c#設計模式系列模板方法模式(Template Method Pattern)

出了 strong view crete question ron 屬於 png 過多 引言 提到模板,大家肯定不免想到生活中的“簡歷模板”、“論文模板”、“Word中模版文件”等,在現實生活中,模板的概念就是——有一個規定的格式,然後每個人都可以根據自己的需求或情況去更

天一設計模式(五) - 適配器模式(Adapter)

p s func 靈活性 nsh ans target 多線程 isp pattern 前言 適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 適配器模式的用途 最經典的就是電器的例子,筆記本電腦的插

天一設計模式(四) - 原型模式(Prototype)

管理員 ans rip prototype register 性能 除了 func comm 前言 原型模式屬於對象的創建模式。通過給出一個原型對象來指明所有創建的對象的類型,然後用這個原型對象提供的復制辦法創建出更多同類型的對象。 原型模式的結構 原型模式要求對象實現

天一設計模式() - 總體概述

享元 關註 責任鏈 分布式 分享圖片 模板方法 mage upload 抽象工廠 前言 最近在對設計模式進行了一系列總結,本文將給大家關於設計模式的一個整體的介紹。 正文 1. 定義 設計模式是某類特定問題的代碼設計解決方案,是一套代碼設計的經驗總結。 2. 作用 提高

設計模式13模板方法模式

模板方法 概念:定義一個操作中演算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變演算法的結構即可重定義該演算法的某些特定步驟 本質:分離演算法,選擇實現。即處理步驟父類中定義好,具體實現延遲到子類中定義 其實這個蠻好懂啦,設想一下,當你和某個老哥一起去銀行辦理業務,你辦理

Java進階篇設計模式之十 ---- 策略模式模板方法模式

前言 在上一篇中我們學習了行為型模式的訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。本篇則來學習下行為型模式的兩個模式,策略模式(Strategy Pattern)和模板模式(Mediator Pattern)。 策略模式 簡介 策略模式(Stra

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

一、定義、型別及類圖 定義:定義一個操作中演算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變演算法的結構即可重定義該演算法中的某些特定步驟。 型別:行為類模式 類圖:第二圖出自——《大話設計模式》 二、示例     事實上,模版方法是程式設計中

設計模式第12篇模板方法模式

一.模板方法模式介紹   模板方法模式中規定了完成一個任務的各個工序的執行順序,同時對某些通用的基礎工序提供了預設的實現。比如給定一個造房子的任務,完成這個任務的工序可以分解為打地基buildFoundation(),建柱子buildPillars(),建牆buildWalls(),裝窗戶buildWind