3.模板模式

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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容