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/