抚州做网站价格多少,零基础怎么学视频剪辑,具权威的小企业网站建设,网站开发者yotoon摘要#xff1a;Template Method模式是比较简单的设计模式之一#xff0c;但它却是代码复用的一项基本的技术#xff0c;在类库中尤其重要。主要内容1#xff0e;概述2#xff0e;Template Method解说3#xff0e;.NET中的Template Method模式4#xff0e;适用性及实现要… 摘要Template Method模式是比较简单的设计模式之一但它却是代码复用的一项基本的技术在类库中尤其重要。 主要内容 1概述 2Template Method解说 3.NET中的Template Method模式 4适用性及实现要点 概述 变化一直以来都是软件设计的永恒话题在XP编程中提倡拥抱变化积极应对。如何更好的去抓住变化点应对变化如何更好的提高代码复用通过学习Template Method模式您应该有一个新的认识。 意图 定义一个操作中的算法的骨架而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[-GOF《设计模式》] 结构图 图1 Template Method 模式结构图 生活中的例子 模板方法定义了一个操作中算法的骨架而将一些步骤延迟到子类中。房屋建筑师在开发新项目时会使用模板方法。一个典型的规划包括一些建筑平面图每个平面图体现了不同部分。在一个平面图中地基、结构、上下水和走线对于每个房间都是一样的。只有在建筑的后期才开始有差别而产生了不同的房屋样式。 图2 使用建筑图为例子的Template Method模式 Template Method模式解说 李建忠老师说过一句话如果你只想掌握一种设计模式的话那这个模式一定是Template Method模式。对于这个问题我想可能是仁者见仁智者见智但是有一点不能否认的Template Method模式是非常简单而且几乎是无处不用很少有人没有用过它。下面我们以一个简单的数据库查询的例子来说明Template Method模式注意这个例子在实际数据库开发中并没有任何实际意义这里仅仅是为了作为示例而已。 假如我们需要简单的读取Northwind数据库中的表的记录并显示出来。对于数据库操作我们知道不管读取的是哪张表它一般都应该经过如下这样的几步 1连接数据库Connect 2执行查询命令Select 3显示数据Display 4断开数据库连接Disconnect 这些步骤是固定的但是对于每一张具体的数据表所执行的查询却是不一样的。显然这需要一个抽象角色给出顶级行为的实现。如下图 图3 Template Method模式的实现方法是从上到下我们首先给出顶级框架DataAccessObject的实现逻辑 public abstract class DataAccessObject{ protected string connectionString; protected DataSet dataSet; public virtual void Connect() { connectionString ServerRj-097;User Idsa;Passwordsa;DatabaseNorthwind; } public abstract void Select(); public abstract void Display(); public virtual void Disconnect() { connectionString ; } // The Template Method public void Run() { Connect(); Select(); Display(); Disconnect(); }} 显然在这个顶级的框架DataAccessObject中给出了固定的轮廓方法Run()便是模版方法Template Method模式也由此而得名。而对于Select()和Display()这两个抽象方法则留给具体的子类去实现如下图 图4 示意性实现代码 class Categories : DataAccessObject{ public override void Select() { string sql select CategoryName from Categories; SqlDataAdapter dataAdapter new SqlDataAdapter( sql, connectionString); dataSet new DataSet(); dataAdapter.Fill(dataSet, Categories); } public override void Display() { Console.WriteLine(Categories ---- ); DataTable dataTable dataSet.Tables[Categories]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row[CategoryName].ToString()); } Console.WriteLine(); }} class Products : DataAccessObject{ public override void Select() { string sql select top 10 ProductName from Products; SqlDataAdapter dataAdapter new SqlDataAdapter( sql, connectionString); dataSet new DataSet(); dataAdapter.Fill(dataSet, Products); } public override void Display() { Console.WriteLine(Products ---- ); DataTable dataTable dataSet.Tables[Products]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row[ProductName].ToString()); } Console.WriteLine(); }} 再来看看客户端程序的调用不需要再去调用每一个步骤的方法 public class App{ static void Main() { DataAccessObject dao; dao new Categories(); dao.Run(); dao new Products(); dao.Run(); // Wait for user Console.Read(); }} 在上面的例子中需要注意的是 1对于Connect()和Disconnect()方法实现为了virtual而Select()和Display()方法则为abstract这是因为如果这个方法有默认的实现则实现为virtual否则为abstract。 2Run()方法作为一个模版方法它的一个重要特征是在基类里定义而且不能够被派生类更改。有时候它是私有方法private method但实际上它经常被声明为protected。它通过调用其它的基类方法覆写过的来工作但它经常是作为初始化过程的一部分被调用的这样就没必要让客户端程序员能够直接调用它了。 3在一开始我们提到了不管读的是哪张数据表它们都有共同的操作步骤即共同点。因此可以说Template Method模式的一个特征就是剥离共同点。 .NET 中的Template Method模式 .NET Framework中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 }} 其中OnSelectionChanged()和OnTextChanged()便是Template Method模式中的基本方法之一也就是子步骤方法它们的调用已经在RichTextBox中实现了。 实现要点 1Template 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模版方法模式(结构型模式)》