.NET 中的Template Method模式
.NET Framework中Template Method模式的使用可以说是无处不在,比如说我们需要自定义一个文本控件,会让它继承于RichTextBox,并重写其中部分事件,如下例所示:
其中OnSelectionChanged()和OnTextChanged()便是Template Method模式中的基本方法之一,也就是子步骤方法,它们的调用已经在RichTextBox中实现了。public class MyRichTextBox : RichTextBox
![]()
{
![]()
private static bool m_bPaint = true;
![]()
private string m_strLine = "";
![]()
private int m_nContentLength = 0;
![]()
private int m_nLineLength = 0;
![]()
private int m_nLineStart = 0;
![]()
private int m_nLineEnd = 0;
![]()
private string m_strKeywords = "";
![]()
private int m_nCurSelection = 0;
![]()
![]()
protected override void OnSelectionChanged(EventArgs e)
![]()
{
m_nContentLength = this.TextLength;
![]()
int nCurrentSelectionStart = SelectionStart;
![]()
int nCurrentSelectionLength = SelectionLength;
![]()
m_bPaint = false;
![]()
m_nLineStart = nCurrentSelectionStart;
![]()
while ((m_nLineStart > 0) && (Text[m_nLineStart - 1] != ',')&& (Text[m_nLineStart - 1] != '{')&& (Text[m_nLineStart - 1] != '('))
![]()
m_nLineStart--;
![]()
m_nLineEnd = nCurrentSelectionStart;
![]()
while ((m_nLineEnd < Text.Length) && (Text[m_nLineEnd] != ',')&& (Text[m_nLineEnd] != '}')&& (Text[m_nLineEnd] != ')')&& (Text[m_nLineEnd] != '{'))
![]()
m_nLineEnd++;
![]()
![]()
m_nLineLength = m_nLineEnd - m_nLineStart;
![]()
m_strLine = Text.Substring(m_nLineStart, m_nLineLength);
![]()
this.SelectionStart = m_nLineStart;
![]()
this.SelectionLength = m_nLineLength;
![]()
![]()
m_bPaint = true;
![]()
}
![]()
protected override void OnTextChanged(EventArgs e)
![]()
{
// 重写OnTextChanged
}
}
实现要点
1.Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
2.除了可以灵活应对子步骤的变化外,“不用调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
3.在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法,纯虚方法),但一般推荐将它们设置为protected方法。[李建忠]
适用性
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是Opdyke和Johnson所描述过的“重分解以一般化”的一个很好的例子。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3.控制子类扩展。模板方法只在特定点调用“Hook”操作,这样就只允许在这些点进行扩展。
总结
Template Method模式是非常简单的一种设计模式,但它却是代码复用的一项基本的技术,在类库中尤其重要。
本篇文章写的比较简单,请大家见谅。更多的设计模式文章可以访问《.NET设计模式系列文章》
参考资料
Erich Gamma等,《设计模式:可复用面向对象软件的基础》,机械工业出版社
Robert C.Martin,《敏捷软件开发:原则、模式与实践》,清华大学出版社
阎宏,《Java与模式》,电子工业出版社
Alan Shalloway James R. Trott,《Design Patterns Explained》,中国电力出版社
MSDN WebCast 《C#面向对象设计模式纵横谈(14):Template Method模版方法模式(结构型模式)》
