1.認識模板方法
模板方法定義了一個算法的步驟,并允許子類為一個或多個步驟提供實現。使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。
鉤子:
鉤子是一種被聲明在抽象類中的方法,但是只有空的或者默認的實現。鉤子的存在,可以讓子類有能力對算法的不同點進行掛鉤
2.注意事項
創建一個模板方法時,怎么樣才能知道,什么時候使用抽象方法,什么時候使用鉤子?
1)當子類必須提供算法中某個方法或者步驟的實現時,使用抽象方法。如果該部分是可選的,使用鉤子。鉤子的真正目的是什么?
1)鉤子可以讓子類實現算法中的可選部分
2)讓子類能夠有機會對模板方法中某些即將發生(或剛剛發生)的步驟作出反應子類必須實現抽象類中的所有方法嗎?
1)是的抽象方法的數目是否越少越好?否則子類需要實現的方法會很多
1)
//炒菜的接口
protocol FryVegetablesType {
func fry() //模板方法,在延展中給出默認實現
func reportTheDishNames() //報菜名,在子類中給出實現
func putSomeOil() //放油,在延展中給出默認實現
func putSomeGreenOnion() //放蔥花,在延展中給出默認實現
func putVegetables() //放蔬菜,在子類中給出具體實現
func putSpices() //放調料,在子類中給出具體實現
func outOfThePan() //出鍋,在延展中給出具體實現
}
//對炒菜接口提供的延展,給出了炒菜中共同的部分和“模板方法”
extension FryVegetablesType {
func fry() {
reportTheDishNames()
putSomeOil()
putSomeGreenOnion()
putVegetables()
putSpices()
outOfThePan()
}
func putSomeOil() {
print("往鍋里放油!")
}
func putSomeGreenOnion() {
print("放蔥花爆香!")
}
func outOfThePan() {
print("出鍋!\n")
}
}
//醋溜土豆絲
class FryShreddedPotatoes: FryVegetablesType {
//報菜名
func reportTheDishNames() {
print("醋溜土豆絲:")
}
func putVegetables() {
print("放土豆絲和青紅椒絲!")
}
func putSpices() {
print("放鹽和醋!")
}
}
//清炒苦瓜
class FryBitterGourd: FryVegetablesType {
func reportTheDishNames() {
print("清炒苦瓜:")
}
func putVegetables() {
print("放苦瓜片和青紅椒片! ")
}
func putSpices() {
print("放鹽!")
}
}
let fryShreddedPotatoes: FryShreddedPotatoes = FryShreddedPotatoes()
fryShreddedPotatoes.fry()
let fryBitterGourd: FryBitterGourd = FryBitterGourd()
fryBitterGourd.fry()
參考資料:
1)《Header First設計模式》
2)青玉伏案
http://www.cnblogs.com/ludashi/