在物件導向程式設計過程中,程式設計師常常會遇到這種情況:設計乙個系統時知道了演算法所需的關鍵步驟,而且確定了這些步驟的執行順序,但某些步驟的具體實現還未知,或者說某些步驟的實現與具體的環境相關。
例如,去銀行辦理業務一般要經過以下4個流程:取號、排隊、辦理具體業務、對銀行工作人員進行評分等,其中取號、排隊和對銀行工作人員進行評分的業務對每個客戶是一樣的,可以在父類中實現,但是辦理具體業務卻因人而異,它可能是存款、取款或者轉賬等,可以延遲到子類中實現。
這樣的例子在生活中還有很多,例如,乙個人每天會起床、吃飯、做事、睡覺等,其中「做事」的內容每天可能不同。我們把這些規定了流程或格式的例項定義成模板,允許使用者根據自己的需求去更新它,例如,簡歷模板、**模板、word 中模板檔案等。
以下介紹的模板方法模式將解決以上類似的問題。
模板方法(template method)模式的定義如下:定義乙個操作中的演算法骨架,而將演算法的一些步驟延遲到子類中,使得子類可以不改變該演算法結構的情況下重定義該演算法的某些特定步驟。它是一種類行為型模式。
該模式的主要優點如下。
它封裝了不變部分,擴充套件可變部分。它把認為是不變部分的演算法封裝到父類中實現,而把可變部分演算法由子類繼承實現,便於子類繼續擴充套件。
它在父類中提取了公共的部分**,便於**復用。
部分方法是由子類實現的,因此子類可以通過擴充套件方式增加相應的功能,符合開閉原則。
該模式的主要缺點如下。
對每個不同的實現都需要定義乙個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象,間接地增加了系統實現的複雜度。
父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這導致一種反向的控制結構,它提高了**閱讀的難度。
由於繼承關係自身的缺點,如果父類新增新的抽象方法,則所有子類都要改一遍。
模板方法模式需要注意抽象類與具體子類之間的協作。它用到了虛函式的多型性技術以及「不用呼叫我,讓我來呼叫你」的反向控制技術。現在來介紹它們的基本結構。
模板方法模式包含以下主要角色。
1)抽象類/抽象模板(abstract class)
抽象模板類,負責給出乙個演算法的輪廓和骨架。它由乙個模板方法和若干個基本方法構成。這些方法的定義如下。
① 模板方法:定義了演算法的骨架,按某種順序呼叫其包含的基本方法。
② 基本方法:是整個演算法中的乙個步驟,包含以下幾種型別。
2)具體子類/具體實現(concrete class)
具體實現類,實現抽象類中所定義的抽象方法和鉤子方法,它們是乙個頂級邏輯的乙個組成步驟。
模板方法的模擬結構圖:
用模板方法模式實現出國留學手續設計程式。
分析:出國留學手續一般經過以下流程:索取學校資料,提出入學申請,辦理因私出國護照、出境卡和公證,申請簽證,體檢、訂機票、準備行裝,抵達目標學校等,其中有些業務對各個學校是一樣的,但有些業務因學校不同而不同,所以比較適合用模板方法模式來實現。
在本例項中,我們先定義乙個出國留學的抽象類 studyabroad,裡面包含了乙個模板方法 templatemethod(),該方法中包含了辦理出國留學手續流程中的各個基本方法,其中有些方法的處理由於各國都一樣,所以在抽象類中就可以實現,但有些方法的處理各國是不同的,必須在其具體子類(如美國留學類 studyinamerica)中實現。如果再增加乙個國家,只要增加乙個子類就可以了
//抽象類: 出國留學
public
abstract
class
studyabroad
public
void()
public
void()
public
void
readygoabroad()
public
abstract
void
lookingforschool()
;//索取學校資料
public
abstract
void()
;//入學申請
public
abstract
void
arriving()
;//抵達
}
//具體子類: 美國留學
public
class
studyinamerica
extends
studyabroad
@override
public
void()
@override
public
void
arriving()
}
public
class
studyabroadprocess
}
模板方法模式通常適用於以下場景。
演算法的整體步驟很固定,但其中個別部分易變時,這時候可以使用模板方法模式,將容易變的部分抽象出來,供子類實現。
當多個子類存在公共的行為時,可以將其提取出來並集中到乙個公共父類中以避免**重複。首先,要識別現有**中的不同之處,並且將不同之處分離為新的操作。最後,用乙個呼叫這些新的操作的模板方法來替換這些不同的**。
當需要控制子類的擴充套件時,模板方法只在特定點呼叫鉤子操作,這樣就只允許在這些點進行擴充套件。
模板方法模式理解
原文 在現實生活中,很多事情都包含幾個實現步驟,例如請客吃飯,無論吃什麼,一般都包含點單 吃東西 買單等幾個步驟,通常情況下這幾個步驟的次序是 點單 吃東西 買單。在這三個步驟中,點單和買單大同小異,最大的區別在於第二步 吃什麼?吃麵條和吃滿漢全席可大不相同,如圖1所示 在軟體開發中,有時也會遇到類...
設計模式初理解
設計模式學習完了,當然是要總結一下的。學習設計模式當然首先要了解什麼是模式啦,模式呢,就是在特定的環境下人們解決某類重複的出現的問題的一套成功或者有效的解決方案。我們從事軟體設計的人員應該了解到在軟體開發生命週期的每乙個階段都存在一些被認同的模式。軟體的模式分為四部分 分別是問題描述 前提條件 解決...
模板方法模式
有這樣乙個場景 乙個演算法或流程,它的步驟以及步驟之間的順序是固定的,但具體的某一步可能有不同的實現。對於這麼乙個場景,可以建立多個類,各個類實現不同的實現,但是這樣的缺點是 易錯 難改,易錯 應為步驟和順序是固定的,而且在每個類中都要寫一遍,程式設計師怎有心情不好的時候,就有可能把其中某一步給寫錯...