在模板方法模式(template method)中,定義乙個演算法的骨架,將具體內容延遲到子類去實現。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。屬於行為性模式。
uml類圖
**示例
下面以衝咖啡和泡茶舉例 傳統寫法:
public
class
coffee
public
void
boilwater()
public
void
brewcoffeegrinds()
public
void
pourincup()
public
void
addsugarandmilk()
}
public
class
teapublic
void
boilwater()
public
void
steepteabag()
public
void
pourincap()
public
void
addlemon()
}
上面兩個步驟是極其相似的,造成了**重複。所以我們可以重構**將部分**放入基類中。
重構:
public
abstract
class
base
public
void
pourincap()
}class
teaextends
base
class
coffee
extends
base
這是基本的解決方法,現在看我們**的重複性降低了。其實泡茶和衝咖啡是很相似的操作,加檸檬和加糖,牛奶也是很相似的操作,可以考慮下是否也將其抽出到子類中呢?
再次重構:
public
abstract
class
templatemethod
/** * 沖泡
*/abstract
void
brew()
;/**
* 增加調料
*/abstract
void
addcondiments()
;void
boilwater()
void
pourincup()
}public
class
coffee
extends
templatemethod
@override
void
addcondiments()
}public
class
teaextends
templatemethod
@override
void
addcondiments()
}
其實這就是***模板方法***模式。模板方法定義了乙個演算法的步驟,並允許子類為乙個或多個步驟提供實現。
思考:倘若客戶不想加糖加牛奶加檸檬呢(加調料)?這樣就需要addcondiments()方法不執行,如何實現?
public
abstract
class
templatemethod
}/**
* 沖泡
*/abstract
void
brew()
;/**
* 增加調料
*/abstract
void
addcondiments()
;void
boilwater()
void
pourincup()
/** * 鉤子方法 可以用來控制演算法執行流程
* 基類可以提供預設實現,由子類決定是否重寫
** @return
*/boolean
customerwantscondiments()
}/**
* 子類需要自己去實現鉤子方法
*/public
class
coffeewithhook
extends
templatemethod
@override
void
addcondiments()
@override
boolean
customerwantscondiments()
}public
class
main
}
測試結果:燒開水
泡茶倒入杯中
加檸檬==
====
*****==
燒開水沖泡咖啡
倒入杯中
加糖和牛奶
====
====
====
=燒開水
沖泡咖啡
倒入杯中
結論:通過子類重寫鉤子方法,達到了控制演算法執行流程的目的。 模板方法模式
有這樣乙個場景 乙個演算法或流程,它的步驟以及步驟之間的順序是固定的,但具體的某一步可能有不同的實現。對於這麼乙個場景,可以建立多個類,各個類實現不同的實現,但是這樣的缺點是 易錯 難改,易錯 應為步驟和順序是固定的,而且在每個類中都要寫一遍,程式設計師怎有心情不好的時候,就有可能把其中某一步給寫錯...
模板方法模式
模板方法模式 定義乙個演算法框架,將裡面的操作步驟推遲到子類中去執行,這樣使得子類不用改變框架,只需改變某些操作步驟方法 ifndef test h define test h include include using namespace std class test virtual test v...
模板方法模式
模板方法模式 在乙個方法中定義乙個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的某些步驟。還可以使用鉤子對可選部分進行判斷。include include using namespace std class caffeinebeverage ...