《大話設計模式》第 10 章 - 模板方法模式 的 Swift 實現。
問題
兩個學生抄試題,各自有不同的答案,試卷是相同的。
方案
當我們要完成在某個細節(jié)層次一致的一個過程或一系列步驟,但其個別步驟在更詳細的層次上的實現可能不同時,我們通??紤]用模板方法模式來處理。
所有重復的代碼都上升到父類去,而不是讓每個子類都去重復。把試題中相同的部分提煉到一個抽象類中。在用 Swift 實現時可以運用 Swift 的特性,把這個抽象類(模板)拆分成一個 protocol 和這個 protocol 的 extension。
1. AbstractClass:定義并實現一個模板方法。
這個模板方法一般是一個具體方法,它給出一個頂級邏輯的骨架。頂級邏輯也有可能調用一些具體方法。
protocol TestPaper{
func answer1() -> String
func answer2() -> String
func answer3() -> String
}
extension TestPaper{
func testQuestion1() {
print("Question 1")
print("Answer: \(answer1())")
}
func testQuestion2() {
print("Question 2")
print("Answer: \(answer2())")
}
func testQuestion3() {
print("Question 3")
print("Answer: \(answer3())")
}
}
2. ConcreteClass:實現 protocol 所定義的方法
使得頂級邏輯的實現各不相同。
class TestPaperA: TestPaper{
func answer1() -> String {
return "b"
}
func answer2() -> String {
return "c"
}
func answer3() -> String {
return "a"
}
}
class TestPaperB: TestPaper{
func answer1() -> String {
return "c"
}
func answer2() -> String {
return "a"
}
func answer3() -> String {
return "a"
}
}
測試
print("Test Paper A:")
let a = TestPaperA()
a.testQuestion1()
a.testQuestion2()
a.testQuestion3()
print("\nTest Paper B:")
let b = TestPaperB()
b.testQuestion1()
b.testQuestion2()
b.testQuestion3()
總結
模板方法:定義一個操作中的算法骨架,將一些步驟延遲到子類中。模板方法可以使子類可以不改變一個算法的結構即可重新定義該算法的某些特定步驟。
模板方法通過把不變的行為搬移到超類,去除子類中的重復代碼來體現它的優(yōu)勢。它提供了一個很好的代碼復用平臺。