五维思考

学习要加,骄傲要减,机会要乘,懒惰要除。 http://www.5dthink.cn

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::


模板方法模式(Template Method Pattern)

模版方法中的方法可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。

  a.模版方法

  一个模版方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
这个模版方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来。

  b.基本方法

  基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和
钩子方法(Hook Method)。

  抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在C#语言里一个抽象方法以abstract
关键字标示出来。

  具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。在C#语言里面,一个具体方法
没有abstract关键字。

  钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,
作为方法的默认实现。(Visual FoxPro中项目向导建立的项目会使用一个AppHook类实现监视项目成员变化,调整系统结构的工作。)钩子方法的名字通常以do开始。



下面讲解窗体基类的模板方法实现:

抽象方法必须定义在抽象类中(Abstract Class),在某些场合不一定使用抽象类,比如frmBase是个具体类,因此我将模板方法改为虚拟(Virtual)的。

        /// <summary>

        /// 在基类定义查询数据的模板方法,由派生窗体实现具体的查询功能。

        /// </summary>

        /// <returns></returns>

        protected virtual DataTable DoSearch()

        {

            return new DataTable(); //模板方法不能返回实际数据。

        }



派生类具体实现:


        //复写(Override)模板方法,具体实现

        protected override DataTable DoSearch()

        {

            return new BLL_Product().Search(txtProductCode.Text, txtProductName.Text);

        }



窗体基类界面:

贴图图片

public partial class frmBase : Form
{
   public frmBase()
   {
      InitializeComponent();
   }
   
   private void btnSearch_Click(object sender, EventArgs e)
   {
      //调用模板方法 
      DataTable data = this.DoSearch();
      
      if (data.Rows.Count > 0)
      this.dataGridView1.DataSource = data;
      else
      MessageBox.Show("没有找到数据!");
   }
   
   /// <summary> 
   /// 在基类定义查询数据的模板方法,由派生窗体实现具体的查询功能。 
   /// </summary> 
   /// <returns></returns> 
   protected virtual DataTable DoSearch()
   {
      return new DataTable(); //模板方法不能返回实际数据。 
   }
   
}


派生一个产品定义窗体:

贴图图片

public partial class frmProduct : CSFramework.TemplateMethodDemo.frmBase
{
   public frmProduct()
   {
      InitializeComponent();
   }
   
   //复写(Override)模块方法,具体实现 
   protected override DataTable DoSearch()
   {
      return new BLL_Product().Search(txtProductCode.Text, txtProductName.Text);
   }
}


搜索功能在窗体基类实现了,我们只需要定义具体的数据查找方法。
通过重写DoSearch模块方法,从业务逻辑层返回数据。


/// <summary>

    /// 业务逻辑层

    /// </summary>

    public class BLL_Product

    {

        public DataTable Search(string productCode, string productName)

        {

            string where = " 1=1 ";

 

            if (!String.IsNullOrEmpty(productCode))

                where = where + " and ProductCode=’" + productCode + "’";

 

            if (!String.IsNullOrEmpty(productName)) //支持模糊查找

                where = where + " and ProductName like ’%" + productName + "%’";

 

            string sql = "select * from tb_Product where " + where;

            //SQL Server 获取数据 ..........省略...........

            //

            //下面返回测试数据

            DataTable test = this.GetDemoData();//返回测试数据

            DataRow[] rows = test.Select(where);

 

            //克隆 System.Data.DataTable 的结构,包括所有 System.Data.DataTable 架构和约束。

            DataTable retTable = test.Clone();

            foreach (DataRow row in rows)

                retTable.ImportRow(row);

 

            return retTable;

        }

 

        /// <summary>

        /// 构建测试数据表

        /// </summary>

        /// <returns></returns>

        private DataTable GetDemoData()

        {

            DataTable dt = new DataTable();

            dt.Columns.Add("ProductCode"typeof(String));

            dt.Columns.Add("ProductName"typeof(String));

            dt.Columns.Add("Price"typeof(Decimal));

 

            dt.Rows.Add("001""原创作品CD", 99);

            dt.Rows.Add("002""Dev Express 9.2x Suit", 9960);

            dt.Rows.Add("003""可口可乐", 1.90);

            dt.Rows.Add("004""Engima CD", 269);

 

            return dt;

        }

    }



posted on 2015-03-12 18:59  五维思考  阅读(209)  评论(0编辑  收藏  举报

QQ群:1. 全栈码农【346906288】2. VBA/VSTO【2660245】