1.認(rèn)識模板方法
模板方法定義了一個(gè)算法的步驟,并允許子類為一個(gè)或多個(gè)步驟提供實(shí)現(xiàn)。使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。
鉤子:
鉤子是一種被聲明在抽象類中的方法,但是只有空的或者默認(rèn)的實(shí)現(xiàn)。鉤子的存在,可以讓子類有能力對算法的不同點(diǎn)進(jìn)行掛鉤
2.注意事項(xiàng)
創(chuàng)建一個(gè)模板方法時(shí),怎么樣才能知道,什么時(shí)候使用抽象方法,什么時(shí)候使用鉤子?
1)當(dāng)子類必須提供算法中某個(gè)方法或者步驟的實(shí)現(xiàn)時(shí),使用抽象方法。如果該部分是可選的,使用鉤子。鉤子的真正目的是什么?
1)鉤子可以讓子類實(shí)現(xiàn)算法中的可選部分
2)讓子類能夠有機(jī)會(huì)對模板方法中某些即將發(fā)生(或剛剛發(fā)生)的步驟作出反應(yīng)子類必須實(shí)現(xiàn)抽象類中的所有方法嗎?
1)是的抽象方法的數(shù)目是否越少越好?否則子類需要實(shí)現(xiàn)的方法會(huì)很多
1)
//炒菜的接口
protocol FryVegetablesType {
func fry() //模板方法,在延展中給出默認(rèn)實(shí)現(xiàn)
func reportTheDishNames() //報(bào)菜名,在子類中給出實(shí)現(xiàn)
func putSomeOil() //放油,在延展中給出默認(rèn)實(shí)現(xiàn)
func putSomeGreenOnion() //放蔥花,在延展中給出默認(rèn)實(shí)現(xiàn)
func putVegetables() //放蔬菜,在子類中給出具體實(shí)現(xiàn)
func putSpices() //放調(diào)料,在子類中給出具體實(shí)現(xiàn)
func outOfThePan() //出鍋,在延展中給出具體實(shí)現(xiàn)
}
//對炒菜接口提供的延展,給出了炒菜中共同的部分和“模板方法”
extension FryVegetablesType {
func fry() {
reportTheDishNames()
putSomeOil()
putSomeGreenOnion()
putVegetables()
putSpices()
outOfThePan()
}
func putSomeOil() {
print("往鍋里放油!")
}
func putSomeGreenOnion() {
print("放蔥花爆香!")
}
func outOfThePan() {
print("出鍋!\n")
}
}
//醋溜土豆絲
class FryShreddedPotatoes: FryVegetablesType {
//報(bào)菜名
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設(shè)計(jì)模式》
2)青玉伏案
http://www.cnblogs.com/ludashi/