換句話說就是基本演算法步驟是一樣的,只不過在某些地方可能有一些改變比如
如果用傳統方法可能就是說不同的演算法實現乙個不同的類,但再來乙個衝燕麥,可能1/4還是一樣的,所以我們想到要把相同的提出來而把不同的封裝出去,可能使用的就是引入2/3兩個類然後再執行方法,但是問題又來了可不可以不這麼麻煩,就是乙個方法嘛,還需要弄個類。
定義衝飲料的超類:
那麼對於沖茶只需要重寫抽象方法就可以了:
泡茶過程:
這個方法優點就是我們的演算法流程是沒有變化的,preparerecipe方法用final修飾表示不能變化。需要修改的**只需要重寫就可以了。
注意:
1、這個和之前說的多用組合少用繼承好像有衝突,其實不是,正所謂具體問題具體分析,之前說的繼承是因為可能會出現大量的重複**,而這個裡面之所以有些方法單獨寫,就是不會出現重合,或者說留這麼乙個方法是讓使用者對於不同的應用不同的方法而言的。其實我認為用組合的方式也不是不可以。
2、模板方法其實更多的體現在給出乙個模板來,然後讓使用者針對這個模板中的某些具體步驟給出實現,這個需要場景應用了。
乙個例子:飲料中是否加入調料。
針對於是否加入調料我們覆蓋該方法:
執行**:
使用了鉤子盡然可以改變演算法流程,非常酷!
就像模板方法模式,高層元件就是咖啡因飲料,雖然裡面有些方法讓子類繼承了,但是子類執行的時候不是來呼叫高層,而是通過高層呼叫低層的。
還有工廠模式和觀察這模式都是按照這個原則的。
#六、具體應用
arrays類中有乙個靜態方法是
public static void sort(object a)
根據元素的自然順序對指定物件陣列按公升序進行排序。陣列中的所有元素都必須實現 comparable 介面。此外,陣列中的所有元素都必須是可相互比較的(也就是說,對於陣列中的任何 e1 和 e2 元素而言,e1.compareto(e2) 不得丟擲 classcastexception)。
上面就是這個演算法的具體流程,但是關於中間如何比較兩個物件的大小是未知的,所以這個部分留給了具體的物件去實現了,之前使用子類繼承超類的方式,因為我們要繼承這個演算法流程,現在是使用靜態方法,是因為你要保證所有陣列都可以,然後如果物件實現了比較的介面,就可以直接呼叫該方法了。
鴨子的實現:
讓我們測試一下這個程式:
1、模板方法定義的是方法的步驟,這些步驟會延遲到子類
2、模板方法抽象類可以定義具體方法,抽象方法和鉤子
3、為了防止子類改變模板方法中的演算法,可以將模板方法申明為final
4、好萊塢規則告訴我們將抉擇權放在高層元件上,來決定如何以及何時呼叫底層模組
5、策略模式和模板方法都是封裝演算法,乙個是組合乙個是繼承
6、工廠方法是模板方法的一種特殊版本。
null
模板方法模式
有這樣乙個場景 乙個演算法或流程,它的步驟以及步驟之間的順序是固定的,但具體的某一步可能有不同的實現。對於這麼乙個場景,可以建立多個類,各個類實現不同的實現,但是這樣的缺點是 易錯 難改,易錯 應為步驟和順序是固定的,而且在每個類中都要寫一遍,程式設計師怎有心情不好的時候,就有可能把其中某一步給寫錯...
模板方法模式
模板方法模式 定義乙個演算法框架,將裡面的操作步驟推遲到子類中去執行,這樣使得子類不用改變框架,只需改變某些操作步驟方法 ifndef test h define test h include include using namespace std class test virtual test v...
模板方法模式
模板方法模式 在乙個方法中定義乙個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的某些步驟。還可以使用鉤子對可選部分進行判斷。include include using namespace std class caffeinebeverage ...