1.1概述 定義了一個操作中演算法的骨架,而將一些步驟延遲到子類中。模板方法使子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。這就是模板方法的定義。 類中的方法用以表明該類的實例所具有的行為,一個類可以有許多方法,而且類中的實例方法也可以調用該類中的其他若幹個方法。在編寫類的時候,可能需要 ...
1.1概述
定義了一個操作中演算法的骨架,而將一些步驟延遲到子類中。模板方法使子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。這就是模板方法的定義。
類中的方法用以表明該類的實例所具有的行為,一個類可以有許多方法,而且類中的實例方法也可以調用該類中的其他若幹個方法。在編寫類的時候,可能需要將類的許多方法集成到一個實例方法中,即用一個實例方法封裝若幹個方法的調用,以表現一個演算法的骨架,也就是說,調用該實例方法相當於按著一定順序執行若幹個方法。
例如,各類客運車站在安排乘客上車時都進行安全檢查、驗證車票、選擇車體類型三個步驟(具體如下圖一所示)。因此在一個抽象類Station中包含安全檢查方法(safetyExamine)、驗證車票方法(validateTicket)、選擇車體類型方法(choiceCarriageType)表示乘車步驟的抽象方法,而且該抽象類中還包含有ridingStep()方法,該方法順序調用安全檢查方法、驗證車票方法、選擇車體類型方法,也就是說抽象類Station使用ridingStep()方法封裝了乘車步驟。ridingStep()方法所調用的safetyExamine()、validateTicket()、choiceCarriageType()方法都是抽象方法,因此Station的子類:RailwayStation(火車站)在實現safetyExamine()、validateTicket()、choiceCarriageType()方法時,分別給出了自己的安全檢查方式、檢票車票方式和所選車體類型。當Station類聲明的變數存放它的子類RailwayStation實例的引用後,該變數就可以調用ridingStep()方法展示乘客的乘車步驟。具體類關係圖如下圖一所示:
圖一:乘車步驟
模板方法是關於怎樣將若幹個方法集成到一個方法中,以便形成一個解決問題的演算法骨架。模板方法模式的關鍵是在一個抽象類中定義一個演算法的骨架,即將若幹個方法集成到一個方法中,並稱該方法為一個模板方法,或簡稱為模板。模板方法所調用的其他方法通常稱為抽象的方法,這些抽象方法相當於演算法骨架中的各個步驟,這些步驟可以由子類去完成。
1.2模式的結構
模板方法模式包括以下兩種角色:
(1)抽象模板(Abstract Template):抽象模板是一個抽象類。抽象模板定義了若幹個方法以表示演算法的各個步驟,這些方法中有抽象方法也有非抽象方法,其中的抽象方法稱為原語操作(Primitive Operation)。重要的一點是,抽象模板中還定義了一個稱之為模板方法的方法,該方法不僅包含有抽象模板中表示演算法步驟的方法調用,而且也可以包含有定義在抽象模板中的其他對象的方法調用,即模板方法定義了演算法的骨架。
(2)具體模板(Concrete Template):具體模板是抽象模板的子類,實現抽象模板中的原語操作。
模板方法模式結構的類圖如下圖二所示:
圖二:模板方法模式的類圖
1.3模板方法模式的優點
(1)可以通過在抽象模板定義模板方法給出成熟的演算法步驟,同時又不限制步驟的細節,具體模板實現細節不會改變整個演算法的框架。
(2)在抽象模板模式中,可以通過鉤子方法對某些步驟進行掛鉤,具體模板通過鉤子可以選擇演算法骨架中的某些步驟。
1.4適合使用模板方法模式的情景
(1)設計者需要給出一個演算法的固定步驟,並將某些步驟的具體實現留給子類來實現。
(2)需要對代碼進行重構,將各個子類公共行為提取出來集中到一個共同的父類中以避免代碼重覆。