现在的位置: 首页 > 综合 > 正文

模板方法模式 :Template Method(转自TerryLee)

2011年02月07日 ⁄ 综合 ⁄ 共 2648字 ⁄ 字号 评论关闭

摘要: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 
= 

            
"Server=Rj-097;User Id=sa;Password=sa;Database=Northwind";

    }


    
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 ---- ");

抱歉!评论已关闭.