模板方法模式定义了一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类能够不改变一个算法的结构就可以重定义该算法的某些特定步骤。
结构图:
AbstractClass是抽象模板。定义并实现一个模板方法,这个模板方法通常是一个详细方法,它给出一个顶级逻辑的骨架。
ConcreteClass是详细模板。实现父类所定义的一个或多个抽象方法。每个AbstractClass能够有随意多个ConcreteClass,每个ConcreteClass都能够给出顶级逻辑的组成步骤。
上面说得比較官方,以下我们通过一个详细的样例来理解一下。
大家都经历了无数次的考试,对这个我们都不太喜欢的过程也非常清楚。首先由出题老师选好考题,然后整理成一套试卷(一个word)。
一. 选择题(每题一分,共10分)
1. 复制的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:
2. 全选的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:
3. 粘贴的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+V d.ctrl+D
答案:
……
这套试卷就是一个抽象模板,它给出试卷的骨架,考生试卷之间同样的部分都包括到这部分中。然后用它去打印n多份试卷,发给每一个同学。所以大家的试题和卷头都是一样的。来自于一个模板。试卷是用来考试的,须要填写答案。因为考生给出的答案不尽同样,编码时把答题写成一个虚方法Answer,让继承它的子类去重写。
我们拿到试卷后,就開始埋头苦“做”,在答题位置写上自己的答案,事实上就是重写Answer。给出抽象方法的不同实现。考试时间到,监考老师收起考生的试卷。考生的试卷就是详细模板。继承抽象模板。
学生甲的试卷:
一. 选择题(每题一分。共10分)
1. 复制的快捷键是a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:b
2. 全选的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:c
3. 粘贴的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+V d.ctrl+D
答案:c
……
学生乙的试卷:
一. 选择题(每题一分,共10分)
1. 复制的快捷键是a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:b
2. 全选的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D
答案:c
3. 粘贴的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+V d.ctrl+D
答案:a
……
分析了半天,接下来展示代码。
class TestPaper { public void TestQuestion1() { Console.WriteLine(" 复制的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D"); Console.WriteLine("答案:" + Answer1()); } public void TestQuestion2() { Console.WriteLine(" 全选的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D"); Console.WriteLine("答案:" + Answer2()); } public void TestQuestion3() { Console.WriteLine(" 粘贴的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+V d.ctrl+D"); Console.WriteLine("答案:" + Answer3()); } protected virtual string Answer1() { return ""; } protected virtual string Answer2() { return ""; } protected virtual string Answer3() { return ""; } } //学生甲的试卷 class TestPaperA:TestPaper { protected override string Answer1() { return "b"; } protected override string Answer2() { return "c"; } protected override string Answer3() { return "c"; } } //学生乙的试卷 class TestPaperB : TestPaper { protected override string Answer1() { return "b"; } protected override string Answer2() { return "c"; } protected override string Answer3() { return "a"; } }
client:
static void Main(string[] args) { Console.WriteLine(" 学生甲抄的试卷:"); TestPaper studentA = new TestPaperA(); studentA.TestQuestion1(); studentA.TestQuestion2(); studentA.TestQuestion3(); Console.WriteLine(" 学生乙抄的试卷:"); TestPaper studentB = new TestPaperB(); studentB.TestQuestion1(); studentB.TestQuestion2(); studentB.TestQuestion3(); }
显示:
最后我们小结一下。纵观上面的小样例,就是有一个过程须要运行,这个过程包含一系列步骤。整个过程从高层次看是一样的,可是每一个步骤的详细细节不一样。模板方法模式就是把不变的搬到超类中,从而去除子类中的反复代码,提供一个代码复用平台。在软件公司中,一个设计师负责给出一个算法的轮廓和骨架,还有一些设计师则负责给出这个算法的各个逻辑步骤。代表这些详细逻辑步骤的方法称做基本方法;而将这些基本法方法总汇起来的方法叫做模版方法。