代码改变世界

【自然框架】——页面基类与设计模式(二) 模板模式

2009-11-25 08:02  金色海洋(jyk)  阅读(2802)  评论(13编辑  收藏  举报

 

前篇:【自然框架】——页面基类与设计模式(一)桥接模式

 

桥接模式的补充:(下面的一段是桥接模式里后补充的一段,桥接模式的一个小结)

 

什么是交接模式?引用《大话设计模式》里的定义:

  桥接模式(Bridge):将抽象部分和他的实现部分分离,使他们都可以独立的变化。(P229)

 

  不知道大家有没有看懂这个定义,至少我是没弄懂,呵呵。再引用一段《大话设计模式》的一段解释:(P232)

 

  小菜:“我觉得交接模式所说的‘将抽象部分和他的实现部分分离’,还是不好理解,我的理解就是实现系统有多个角度分类,每一种分类都有可能有变化,那么就把这种多角度分离出来让他们独立变化,减少他们之间的耦合。”

 

  这个就是作者(程杰)的理解吧,这个解释够白话的了,不过我还想说一下我的更加白话的理解,呵呵。大家看看对不对。

 

  我的理解就是:有两套或者多套独立的“多态系统”,他们可以各自独立的变化(继承),互不干扰。然后选择一套系统作为容器,在这个容器里定义其他系统的实例或者借口,通过这种关系(组合/聚合)把两套或者多套系统结合起来,配合工作。组合/聚合就好像一座桥梁一样把这些系统结合在一起,所以就叫做桥接模式了。

 

  就好比我的这个例子里面,页面基类就是一套“多态系统”,他可以派生出列表页面基类、表单页面基类等,把页面基类作为容器,在其内部定义数据访问函数库的实例,定义当前登录人信息的实例。而数据访问函数库还可以自行派生出SqlClient的访问类、OleDb的访问类,他们是独立的“多态系统”互不干扰。页面基类如何变化不需要考虑数据访问的问题,数据访问函数库如何变化也不用考虑有多少种页面。这就是所谓的减少耦合吧。

 

 

=====================================================

 

   

  如果我们在页面基类里要做一些事情,需要制定一下执行顺序,而且有一些处理方法是公用的,但是有一些处理的方式又不一样,这时候就比较适合采用模板模式了。

  比如我们在页面基类里override 一下OnInit(EventArgs e),在这里制定一下执行顺序,然后定义几个虚函数(virtual)。代码如下:

 

 

 

/// <summary>
        
/// 提取URL里面的参数,验证参数
        
/// </summary>
        
/// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            
base.OnInit(e);

            
//调用函数来设置FunctionID,不同类型的页面就可以用不同的方式来设置FunctionID了。
            SetFunctionID();
            
//调用函数来设置ButtonID。
            SetButtonID();

            
//调用函数来设置DataID。
            SetDataID();

            
//调用函数来设置DepartmentID(部门ID)。
            SetDepartmentID();

            
//调用函数来设置ForeignID(外键ID)。
            SetForeignID();

            
if (!Page.IsPostBack)
            {
                
//设置标题
                SetPageTitle();
            }
        }

 

SetFunctionID()的代码,其他代码略。

 /// <summary>
        
/// 设置FunctionID。
        
/// </summary>
        protected virtual void SetFunctionID()
        {
            
//DataList.aspx、DataForm.aspx 页面通过URL里的参数设置。
            
//其他页面自行设置

            
this.FunctionID = Request.QueryString["fid"];
            
#region 验证模块ID参数是否是数字。
            
if (!Functions.IsInt(this.FunctionID))
            {
                Response.Write(
"模块参数不正确!");
                Response.End();
            }
            
#endregion

        }

 

 

  这样子类就继承了基类的执行顺序,然后如果有不一样的验证方式,那么就override一下就可以了。

 

  这样做的好处就是,把共用的东西放到父类,子类只需要关注不一样的地方。同时也强制了编写规范,基类是写好的,大家不能随便修改,如果有不同的需求,可以去改子类(override),不必去改基类,这样也遵守了开放封闭原则。

 

  同理,列表页面基类也采用了模板模式。

  在自然框架里面列表页面里需要使用分页控件、查询控件、数据显示控件、操作按钮组这几个控件,那么给这些控件设置属性值的操作,和他们之间的关联关系就可以放在列表页面基类里去做。代码如下:

 

 

 /// <summary>
        
/// 在 OnInit 事件里面设置各个自定义控件的属性和关联
        
/// </summary>
        
/// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            
//父类里面验证参数是否正确
            base.OnInit(e);

            
//验证是否有权限访问。
            MyUser.CheckFunctionID(this.FunctionID);

            
//设置分页控件的属性和事件
            SetQuickPagerInfo();

            
//设置数据表格的属性
            SetGridInfo();

            
//设置查询控件的属性
            SetFindControlInfo();

            
//设置操作按钮的属性
            SetButtonBarInfo();

        }

 

 

  虽然大多数列表页面都可以这么设置,但是也不排除特殊需求,如果又不一样的需求的话,那么就可以在子类里面通过override的方式来实现自己的特殊需求。

还是那句话,把共用的放在基类里面,子类只关心不同点即可。

 

模板模式的定义:
  还是引用《大话设计模式》里的定义。

 

  模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模版方法可以使得子类可以不修改一个算法的结构既可以重定义该算法的某些特定步骤。【P96】

  

  当然我这里说的只是模板模式的一种形式的应用,除了这种形式的用法外还有很多种形式的用法。

 

  全部源代码下载:http://www.cnblogs.com/jyk/archive/2009/10/28/1591680.html  

 

=============================================

 

白天不能上网,被屏蔽了,所以白天就不能及时回复了,晚上在回复。

 

2