模板方法模式定义了一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
结构图:

AbstractClass是抽象模板,定义并实现一个模板方法,这个模板方法一般是一个具体方法,它给出一个顶级逻辑的骨架。
ConcreteClass是具体模板,实现父类所定义的一个或多个抽象方法,每一个AbstractClass可以有任意多个ConcreteClass,每一个ConcreteClass都可以给出顶级逻辑的组成步骤。< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+yc/D5su1tcOxyL3Pudm3vaOsz8LD5s7Sw8fNqLn90ru49r7fzOW1xMD919PAtMDtveLSu8/CoaM8L3A+CjxwPjxicj4KPC9wPgo8cD6087zStry+rcD6wcvO3sr9tM61xL+8ytSjrLbU1eK49s7Sw8e2vLK7zKvPsru2tcS5/bPM0rK63Mfls/6ho8rXz8jTybP2zOLAz8qm0aG6w7+8zOKjrMi7uvPV+8Dts8nSu8zXytS+7aOo0ru49ndvcmSjqaGjPC9wPgo8cD48L3A+CjxwPjxzdHJvbmc+0rujriAgICAgINGh1PHM4qOow7/M4tK7t9ajrLmyMTC31qOpPC9zdHJvbmc+PC9wPgo8cD4xLiAgICAgILi01sa1xL/svd28/MrHob6hv2EuY3RybCYjNDM7QSAgYi5jdHJsJiM0MztDICBjLmN0cmwmIzQzO0wgZC5jdHJsJiM0MztEPC9wPgo8cD608LC4o7ogPC9wPgo8cD4yLiAgICAgIMir0aG1xL/svd28/MrHob6hv2EuY3RybCYjNDM7QSAgYi5jdHJsJiM0MztDICBjLmN0cmwmIzQzO0wgZC5jdHJsJiM0MztEPC9wPgo8cD608LC4o7ogPC9wPgo8cD4zLiAgICAgINWzzPm1xL/svd28/MrHob6hv2EuY3RybCYjNDM7QSAgYi5jdHJsJiM0MztDICBjLmN0cmwmIzQzO1YgZC5jdHJsJiM0MztEPC9wPgo8cD608LC4o7o8L3A+CjxwPiChraGtPC9wPgrV4szXytS+7b7NysfSu7j2s+nP88SjsOWjrMv8uPiz9srUvu21xLnHvNyjrL+8yfrK1L7t1q685M/gzay1xLK/t9a2vLD8uqy1vdXisr+31tbQoaPIu7rz08PL/MiltPLToW624LfdytS+7aOst6K4+MO/uPbNrNGno6zL+dLUtPO80rXEytTM4rrNvu3Nt7a8ysfSu9H5tcSjrMC019TT2tK7uPbEo7DloaPK1L7tysfTw8C0v7zK1LXEo6zQ6NKqzO7QtLTwsLiho9PJ09q/vMn6uPiz9rXEtPCwuLK7vqHP4M2so6yx4MLryrGw0bTwzOLQtLPJ0ru49tDpt723qEFuc3dlcqOsyMO8zLPQy/y1xNfTwODIpdbY0LShozxicj4KCjxwPs7Sw8fEw7W9ytS+7brzo6y+zb+qyrzC8c23v+ChsNf2obGjrNTatPDM4s671sPQtMnP19S8urXEtPCwuKOsxuTKtb7NysfW2NC0QW5zd2Vyo6y4+LP2s+nP87e9t6i1xLK7zazKtc/WoaO/vMrUyrG85LW9o6y84L+8wM/KpsrVxvC/vMn6tcTK1L7toaO/vMn6tcTK1L7tvs3Kx77fzOXEo7Dlo6y8zLPQs+nP88SjsOWhozxicj4KPC9wPgo8cD7Rp8n6vNe1xMrUvu2jujwvcD4KPHA+PC9wPgo8cD48c3Ryb25nPtK7o64gICAgICAgICAg0aHU8czio6jDv8zi0ru31qOsubIxMLfWo6k8L3N0cm9uZz48L3A+CjxwPjEuICAgICAguLTWxrXEv+y93bz8ysdhLmN0cmwmIzQzO0EgIGIuY3RybCYjNDM7QyAgYy5jdHJsJiM0MztMIGQuY3RybCYjNDM7RDwvcD4KPHA+tPCwuKO6YiA8L3A+CjxwPjIuICAgICAgyKvRobXEv+y93bz8ysehvqG/YS5jdHJsJiM0MztBICBiLmN0cmwmIzQzO0MgIGMuY3RybCYjNDM7TCBkLmN0cmwmIzQzO0Q8L3A+CjxwPrTwsLijumMgPC9wPgo8cD4zLiAgICAgINWzzPm1xL/svd28/MrHob6hv2EuY3RybCYjNDM7QSAgYi5jdHJsJiM0MztDICBjLmN0cmwmIzQzO1YgZC5jdHJsJiM0MztEPC9wPgo8cD608LC4o7pjPC9wPgo8cD4gICAgoa2hrTwvcD4KPHA+0afJ+tLStcTK1L7to7o8L3A+CjxwPjwvcD4KPHA+PHN0cm9uZz7Su6OuICAgICAgICAgINGh1PHM4qOow7/M4tK7t9ajrLmyMTC31qOpPC9zdHJvbmc+PC9wPgo8cD4xLiAgICAgILi01sa1xL/svd28/MrHYS5jdHJsJiM0MztBICBiLmN0cmwmIzQzO0MgIGMuY3RybCYjNDM7TCBkLmN0cmwmIzQzO0Q8L3A+CjxwPrTwsLijumIgPC9wPgo8cD4yLiAgICAgIMir0aG1xL/svd28/MrHob6hv2EuY3RybCYjNDM7QSAgYi5jdHJsJiM0MztDICBjLmN0cmwmIzQzO0wgZC5jdHJsJiM0MztEPC9wPgo8cD608LC4o7pjIDwvcD4KPHA+My4gICAgICDVs8z5tcS/7L3dvPzKx6G+ob9hLmN0cmwmIzQzO0EgIGIuY3RybCYjNDM7QyAgYy5jdHJsJiM0MztWIGQuY3RybCYjNDM7RDwvcD4KPHA+tPCwuKO6YTwvcD4KPHA+ICAgIKGtoa08L3A+CrfWzvbBy7DrzOyjrL3Tz8LAtNW5yr60+sLroaMKPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">class TestPaper { public void TestQuestion1() { Console.WriteLine("\n复制的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D"); Console.WriteLine("答案:" + Answer1()); } public void TestQuestion2() { Console.WriteLine("\n全选的快捷键是【】a.ctrl+A b.ctrl+C c.ctrl+L d.ctrl+D"); Console.WriteLine("答案:" + Answer2()); } public void TestQuestion3() { Console.WriteLine("\n粘贴的快捷键是【】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"; } }
客户端:
static void Main(string[] args)
{
Console.WriteLine("\n学生甲抄的试卷:");
TestPaper studentA = new TestPaperA();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine("\n学生乙抄的试卷:");
TestPaper studentB = new TestPaperB();
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();
}
显示:

最后我们小结一下。纵观上面的小例子,就是有一个过程需要执行,这个过程包括一系列步骤,整个过程从高层次看是一样的,但是每个步骤的具体细节不一样。模板方法模式就是把不变的搬到超类中,从而去除子类中的重复代码,提供一个代码复用平台。在软件公司中,一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法;而将这些基本法方法总汇起来的方法叫做模版方法。