定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
名称 |
Template Method |
结构 |
![](/images/cnblogs_com/darkangel/Template.gif) |
意图 |
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 |
适用性 |
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是O p d y k e 和J o h n s o n 所描述过的“重分解以一般化”的一个很好的例子[ O J 9 3 ]。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
- 控制子类扩展。模板方法只在特定点调用“h o o k ”操作(参见效果一节),这样就只允许在这些点进行扩展。
|
Code Example |
1 // Template Method 2![](/Images/OutliningIndicators/None.gif) 3 // Intent: "Define the skeleton of an algorithm in an operation, deferring 4 // some steps to subclasses. Template Method lets subclasses redefine 5 // certain steps of an algorithm without changing the algorithm's structure." 6![](/Images/OutliningIndicators/None.gif) 7 // For further information, read "Design Patterns", p325, Gamma et al., 8 // Addison-Wesley, ISBN:0-201-63361-2 9![](/Images/OutliningIndicators/None.gif) 10![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//* Notes: 11 * If you have an algorithm with multiple steps, and it could be helpful 12 * to make some of those steps replaceable, but no the entire algorithm, then 13 * use the Template method. 14 * 15 * If the programming language in use supports generics / templates (C# does 16 * not), then they could be used here. It would be educational to take a 17 * good look at the way algorithms in ISO C++'s STL work. 18 */ 19 20 namespace TemplateMethod_DesignPattern 21![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) { 22 using System; 23![](/Images/OutliningIndicators/InBlock.gif) 24 class Algorithm 25![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 26 public void DoAlgorithm() 27![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 28 Console.WriteLine("In DoAlgorithm"); 29 30 // do some part of the algorithm here 31 32 // step1 goes here 33 Console.WriteLine("In Algorithm - DoAlgoStep1"); 34 // . . . 35![](/Images/OutliningIndicators/InBlock.gif) 36 // step 2 goes here 37 Console.WriteLine("In Algorithm - DoAlgoStep2"); 38 // . . . 39![](/Images/OutliningIndicators/InBlock.gif) 40 // Now call configurable/replacable part 41 DoAlgoStep3(); 42![](/Images/OutliningIndicators/InBlock.gif) 43 // step 4 goes here 44 Console.WriteLine("In Algorithm - DoAlgoStep4"); 45 // . . . 46![](/Images/OutliningIndicators/InBlock.gif) 47 // Now call next configurable part 48 DoAlgoStep5(); 49 } 50![](/Images/OutliningIndicators/InBlock.gif) 51 virtual public void DoAlgoStep3() 52![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 53 Console.WriteLine("In Algorithm - DoAlgoStep3"); 54 } 55![](/Images/OutliningIndicators/InBlock.gif) 56 virtual public void DoAlgoStep5() 57![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 58 Console.WriteLine("In Algorithm - DoAlgoStep5"); 59 } 60 } 61![](/Images/OutliningIndicators/InBlock.gif) 62 class CustomAlgorithm : Algorithm 63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 64 public override void DoAlgoStep3() 65![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 66 Console.WriteLine("In CustomAlgorithm - DoAlgoStep3"); 67 } 68![](/Images/OutliningIndicators/InBlock.gif) 69 public override void DoAlgoStep5() 70![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 71 Console.WriteLine("In CustomAlgorithm - DoAlgoStep5"); 72 } 73 } 74![](/Images/OutliningIndicators/InBlock.gif) 75![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) /**//// <summary> 76 /// Summary description for Client. 77 /// </summary> 78 public class Client 79![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 80 public static int Main(string[] args) 81![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 82 CustomAlgorithm c = new CustomAlgorithm(); 83![](/Images/OutliningIndicators/InBlock.gif) 84 c.DoAlgorithm(); 85![](/Images/OutliningIndicators/InBlock.gif) 86 return 0; 87 } 88 } 89 } 90![](/Images/OutliningIndicators/None.gif) |