一、說白了
所謂模板方法模式,說白了就是:例如我請客吃飯,步驟就是點菜、吃東西、結賬。點菜和結賬固定不變,吃東西我們只知道要吃,但具體吃什么放到子類里實現。這就形成了一種模板。
二、定義
模板方法模式:定義一個操作中算法的框架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
Template Method Pattern: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
第一點:定義一個操作中的算法框架
第二點:將一些步驟延時到子類實現
第三點:子類可以不改變算法結構,可以重新定義算法某些特定的功能步驟
三、類型
模板方法模式是一種基于繼承的代碼復用技術,它是一種類行為型模式。
模板方法模式是結構最簡單的行為型設計模式,在其結構中只存在父類與子類之間的繼承關系。通過使用模板方法模式,可以將一些復雜流程的實現步驟封裝在一系列基本方法中,在抽象父類中提供一個稱之為模板方法的方法來定義這些基本方法的執行次序,而通過其子類來覆蓋某些步驟,從而使得相同的算法框架可以有不同的執行結果。模板方法模式提供了一個模板方法來定義算法框架,而某些具體步驟的實現可以在其子類中完成。
四、場景
場景一:多個子類有公共方法,并且邏輯基本相同
場景二:重復、復雜算法,將核心算法設計為模版方法模式,其周邊的細節可以有子類去實現
場景三:代碼重構(通常情況下就會用到模版方法模式)
模板方法模式是基于繼承的代碼復用技術,它體現了面向對象的諸多重要思想,是一種使用較為頻繁的模式。模板方法模式廣泛應用于框架設計中,以確保通過父類來控制處理流程的邏輯順序(如框架的初始化,測試流程的設置等)。
在以下情況下可以考慮使用模板方法模式:
(1) 對一些復雜的算法進行分割,將其算法中固定不變的部分設計為模板方法和父類具體方法,而一些可以改變的細節由其子類來實現。即:一次性實現一個算法的不變部分,并將可變的行為留給子類來實現。
(2) 各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。
(3) 需要通過子類來決定父類算法中某個步驟是否執行,實現子類對父類的反向控制。
五、角色劃分
角色一:抽象類(定義了算法框架結構,將一些特定的步驟延時到子類實現)
角色二:具體模版類(不改變算法結構)
角色三:客戶端
不同的理解不同的劃分,也可以讓模板方法模式理解成如下兩個角色:
(1) AbstractClass(抽象類):在抽象類中定義了一系列基本操作(PrimitiveOperations),這些基本操作可以是具體的,也可以是抽象的,每一個基本操作對應算法的一個步驟,在其子類中可以重定義或實現這些步驟。同時,在抽象類中實現了一個模板方法(Template Method),用于定義一個算法的框架,模板方法不僅可以調用在抽象類中實現的基本方法,也可以調用在抽象類的子類中實現的基本方法,還可以調用其他對象中的方法。
(2) ConcreteClass(具體子類):它是抽象類的子類,用于實現在父類中聲明的抽象基本操作以完成子類特定算法的步驟,也可以覆蓋在父類中已經實現的具體基本操作。
六、基本方法
基本方法是實現算法各個步驟的方法,是模板方法的組成部分?;痉椒ㄓ挚梢苑譃槿N:抽象方法(Abstract Method)、具體方法(Concrete Method)和鉤子方法(Hook Method)。
(1) 抽象方法:一個抽象方法由抽象類聲明、由其具體子類實現。在C#語言里一個抽象方法以abstract關鍵字標識。
(2) 具體方法:一個具體方法由一個抽象類或具體類聲明并實現,其子類可以進行覆蓋也可以直接繼承。
(3) 鉤子方法:一個鉤子方法由一個抽象類或具體類聲明并實現,而其子類可能會加以擴展。通常在父類中給出的實現是一個空實現(可使用virtual關鍵字將其定義為虛函數),并以該空實現作為方法的默認實現,當然鉤子方法也可以提供一個非空的默認實現。
在模板方法模式中,鉤子方法有兩類:第一類鉤子方法可以與一些具體步驟“掛鉤”,以實現在不同條件下執行模板方法中的不同步驟,這類鉤子方法的返回類型通常是bool類型的,用于對某個條件進行判斷,如果條件滿足則執行某一步驟,否則將不執行。