《大话设计模式》第 10 章 - 模板方法模式 的 Swift 实现。
问题
两个学生抄试题,各自有不同的答案,试卷是相同的。
方案
当我们要完成在某个细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
所有重复的代码都上升到父类去,而不是让每个子类都去重复。把试题中相同的部分提炼到一个抽象类中。在用 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()
总结
模板方法:定义一个操作中的算法骨架,将一些步骤延迟到子类中。模板方法可以使子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
模板方法通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势。它提供了一个很好的代码复用平台。
网友评论