一、模板方法模式简介(Brief Introduction)
模板方法模式(Template Method Pattern),定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可以重定义算法的某些特定步骤。模板方法模式把不变行为搬移到超类,从而去除子类中的重复代码,实际上模板方法模式就是提供了一个代码复用平台。
二、解决的问题(What To Solve)
要完成在某一细节上层次一致的一个过程或一系列步骤,但个别步骤在更详细的层次上实现不同时,可以使用模版方法模式解决问题。
三、模板方法模式分析(Analysis)
1、模板方法模式结构
抽象类AbstractClass,实现了一个模版方法,定义了一个算法框架,具体子类将重新定义PrimitiveOperation1和PrimitiveOperation1以实现一个算法的步骤。
子类ConcreteClassA和ConcreteClassB,实现PrimitiveOperation1和PrimitiveOperation1以完成算法中与特定子类相关的步骤。
2、模板方法模式代码
1、抽象模板类AbstractClass及其模板方法TemplateMethod() |
public abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2();
public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine("模板方法执行完"); } } |
2、子类ConcreteClassA、ConcreteClassB实现父类定义的抽象方法 |
public class ConcreteClassA:AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体实现类{0}方法1实现",this.GetType().Name); }
public override void PrimitiveOperation2() { Console.WriteLine("具体实现类{0}方法2实现", this.GetType().Name); } }
public class ConcreteClassB:AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体实现类{0}方法1实现", this.GetType().Name); }
public override void PrimitiveOperation2() { Console.WriteLine("具体实现类{0}方法2实现", this.GetType().Name); } } |
3、客户端代码
|
static void Main(string[] args) { AbstractClass abstractClass = new ConcreteClassA(); abstractClass.TemplateMethod();
abstractClass = new ConcreteClassB(); abstractClass.TemplateMethod();
Console.ReadKey(); } |
3、模板方法模式运行结果
四.实例分析(Example)
1、场景
定义一个数据操作Select的骨架,即Connect连接数据库,Select查询数据返回到数据集DataSet,对得到的结果DataSet进行处理Process查询符合自己的数据。Connect和Run是公用的可以放到抽象类DataAccessObject中,特定步骤Select和Process交由子类来处理。结构如下图所示
DataAccessObject类:定义了一个算法框架,具体子类将重新定义Select和Process操作。
子类Categories和Products:分别实现父类的Select和Process操作
2、代码
1、抽象模板类DataAccessObject及其模板方法Run |
abstract class DataAccessObject { protected string connectionString; protected DataSet dataSet; public virtual void Connect() { // Make sure mdb is available to app connectionString = "provider=Microsoft.JET.OLEDB.4.0;" +"data source=..\\..\\..\\db1.mdb"; } public abstract void Select(); public abstract void Process(); public virtual void Disconnect() { connectionString = ""; }
// The 'Template Method' public void Run() { Connect(); Select(); Process(); Disconnect(); } } |
2、子类Categories和Products实现模板类中的方法Select、Process |
class Categories : DataAccessObject { public override void Select() { string sql = "select CategoryName from Categories"; OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connectionString); dataSet = new DataSet(); dataAdapter.Fill(dataSet, "Categories"); } public override void Process() { Console.WriteLine("Categories ---- "); DataTable dataTable = dataSet.Tables["Categories"]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row["CategoryName"]); } Console.WriteLine(); } } class Products : DataAccessObject { public override void Select() { string sql = "select ProductName from Products"; OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connectionString); dataSet = new DataSet(); dataAdapter.Fill(dataSet, "Products"); }
public override void Process() { Console.WriteLine("Products ---- "); DataTable dataTable = dataSet.Tables["Products"]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row["ProductName"]); } Console.WriteLine(); }
} |
3、客户端代码
|
static void Main(string[] args) { DataAccessObject daoCategories = new Categories();
daoCategories.Run(); DataAccessObject daoProducts = new Products(); daoProducts.Run(); Console.ReadKey(); } |
3、实例运行结果
五、总结(Summary)
本文对模板方法模式设计思想、结构和结构代码进行了分析,并以一实例数据操作进一步阐述了模板方法模式的设计及其C#实现。
版权
作者:灵动生活 郝宪玮
出处:http://www.cnblogs.com/ywqu
如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章,
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。