【自然框架】 页面里的父类—— 改进和想法、解释


 

1、 从Control到GridView继承了多少层?

(这个图可不是现做的,这是以前为了写QuickPager分页控件而弄的。http://www.cnblogs.com/jyk/archive/2009/04/29/1446033.html ) 


      看上面的类图,远远超过三层了吧。如果简单的用“书上说,继承不能超过三层”、“组合优于继承”来衡量的话,那么.Net框架能得到什么样的结论呢?
      所以我说,简单的依靠“书上说”来作评价是很死板的,是根本就没有考虑具体的情况、没有仔细的了解而随便说的。

      当然我并不是说.Net框架继承了这么多层,我就可以多继承几层了,我完全没有这个意思。用不用继承,继承的层数,这个要根据具体问题具体分析的,不能简单的依据书上的话、很随意的做出结论。也不能被书上的话给框框死,就是“尽信书不如无书”吧。


2、 我为什么要用继承。

      我们在做CRM这一类的管理程序的时候,需要做很多的列表页面,这些页面都共同的几件事情要做,判断是否登录、判断是否有权限访问、验证URL参数、给属性赋值等(这个是依据自然框架来说的,对于您来说也许没有这么多,但是总会有共同的事情吧,如果没有那就不需要用继承了)。很显然这些相同的事情不能让每个列表页面都亲自处理一遍,这个工作效率就太低了,冗余代码也很多。那么怎么办呢?我想到的就是继承。建立一个父类,把这些事情都交给父类去做,子类“坐享其成”就可以了。


3、 组合
      上面说了,要把这些共同的事情交给父类去做,那么是不是说就一定要父类亲自去做呢?很显然不是的。比如验证是否登录,这个我就是定义了UserManage、BaseUserInfo两个类来处理的。而在父类里面就是通过这两个类来实现判断是否登录的功能的,这个是不是传说中的“has A”呢?再弱弱的问一下,这个是不是组合呢?(这个我确实比较模糊,是“has A”比较有把握,但是算不算组合就真的不清楚了,望指教)。

如果要把共同的事情都做成类,然后组合的话,那么看看我们要做多少?
 判断是否登录
 判断是否有权限访问
 判断URL参数,每个页面的参数不尽相同,FunctionID是都会传递的,DataID是表单页面的,DepartmentID有时候会有。
 给属性赋值,不同类型的页面,赋值的方法是不一样的。

      这么多的“选项”,并不是每一个页面都需要,有的需要一个,有的需要几个,那么是不是要做出选择呢?如果我有100个列表页面,每一个页面都要选择一下吗?这100个列表页面的选择都是一样的呀,每个页面都做一次,是不是重复了呀。所以还是需要做一个父类,让父类去做选择,子类还是“坐享其成”就可以了。表单页面也是相同的情况。所以我觉得即使用了组合,那么继承的层数还是这些,不会有任何的影响。呵呵。

      所以我才定义了三个父类:列表页面的父类、表单页面的父类、删除页面的父类。如果继承只是这样的话(一层),那么我估计大家也就没有什么异议了吧。但是我又让这三个父类继承了一个父类——PageURL(判断URL的),估计这个是大家看不惯的地方吧,因为这个用OO的思路是完全解释不通的,他们有父子关系吗?没有。既然没有,那么为什么要用继承?为什么不把判断URL的地方做成单独的类,然后再去调用,就像判断是否登录的那样?

      我这么做的目的很简单,就是为了把相同的功能放到父类里面去,至于有没有父子关系,我不想过多的考虑,就像以前大家讨论“book.Save()”是否OO一样,管他O不O呢,好用就行,不用特意去迎合在现实里面的意义吧。既然都需要判断URL参数,那就放在父类里面好了。

      当然,判断URL参数的地方没有做成单独的类还有一个原因,那就是每一类的页面的判断的参数都不一样,还有一些特殊的页面判断的方式也不一样,我把判断的函数定义成virtual的,这样如果子类的判断方式不一样的话,那么就可以通过override来重写成自己的判断方式,这个不知道做成单独的类是否可以达到这样的功能。比如说表单页面的父类就override了验证DataID的函数。


4、 修改。
      看了大家的回复,也确实觉得有一个地方确实不适合,那就是判断是否有权限访问页面的功能,于是思考了一下,应该把这个功能从父类里面移出去,移出去后放在了BaseUserInfo类里面了。

5、修改后的类图


      
      这是我的想法,欢迎大家拍板砖,呵呵。

      好像大家都没有时间下载代码,我就挑点主要的发一下吧。完整代码下载:http://www.cnblogs.com/jyk/archive/2009/09/09/1563246.html

1、PageURL

namespace  Nature.UI.Base
{
    
/// <summary>
    
/// 处理URL参数
    
/// 接收URL传递过来的模块ID,大部分页面都需要使用这个ID
    
/// </summary>

    public partial class PageURL : PagePermission
    
{
        
定义属性,记录URL参数值

        
/// <summary>
        
/// 页面里的标题
        
/// </summary>

        public Label Lbl_Title;             //页面里的标题

        
初始化 在Page_Load之间执行


        
清除IE缓存

       
    }

}

 

namespace  Nature.UI.Base
{
    
/// <summary>
    
/// 说明
    
/// </summary>

    public partial class PageURL : PagePermission
    
{
        
设置标题


        
用抽象函数的方式设置FunctionID

        
用抽象函数的方式设置DataID

        
用抽象函数的方式设置ButtonID

        
验证外键

        
验证部门ID

    }

}


2、BasePageList

namespace  Nature.UI.Base
{
    
/// <summary>
    
/// 列表页面的基类
    
/// 这个算不算模板模式呢?
    
/// </summary>

    public partial class BasePageList : PageURL
    
{
        
定义共用的控件,以便于统一控制

        
在 OnInit 事件里面设置各个自定义控件的属性和关联

    }

}


namespace  Nature.UI.Base
{
    
/// <summary>
    
/// 列表的基类。给共用控件设置属性和事件。
    
/// </summary>

    public partial class BasePageList : PageURL
    
{
        
设置分页控件的属性

        
设置显示数据控件的属性


        
设置查询控件的属性

        
查询按钮触发的事件


        
设置按钮组

        
//验证
        验证DataID

        
验证列表页面与FunctionID是否匹配

    }

}


3、具体的列表页面

namespace  Nature.UI.Common
{
    
/// <summary>
    
/// 数据列表
    
/// </summary>

    public partial class DataList1 : Base.BasePageList  
    
{
        
/// <summary>
        
/// 是否显示查询条件
        
/// </summary>

        protected string isShowSearch = "";        //是否显示查询

        
/// <summary>
        
/// 
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        protected void Page_Load(object sender, EventArgs e)
        
{
            
base.ForeignID = this.DataID;
        }


        
刷新当前页面

        
查询

        
导出到Excel

    }

}




 

< head  runat ="server" >
    
< title > <% = Lbl_Title.Text %> </ title >
    
<% = CssWeb %>  
    
< script  language ="javascript"  type ="text/javascript"  src ="/public/js/TableTR.js"   ></ script >
    
< script  language ="javascript"  type ="text/javascript"  src ="/public/js/My97DatePicker/WdatePicker.js"   ></ script >
    
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
    
< div  style ="width:100%; font-size:14pt; text-align: center;vertical-align:middle;" >
        
< br  />< asp:Label  ID ="Lbl_Title"  runat ="server"  style ="font-size:14pt; " ></ asp:Label >
    
</ div >
    
< Nature:OperationButtonBar  ID ="ctl_CommonButtonBar"  runat ="server"   />
    
< div  id ="div_Search"  style ="display:none;"  align ="center" >< br  />
    
< fieldset  title ="查询条件"  style ="PADDING-BOTTOM:6px;BORDER-RIGHT: #666 1px solid; BORDER-TOP: #ddd 1px solid; BORDER-LEFT: #ddd 1px solid; BORDER-BOTTOM: #666 1px solid;" >< legend  style ="font-size:9pt;" > 查询条件 </ legend >
        
< table   width ="100%"  align ="center"  border ="0"  bgcolor ="#ffffff" >
            
< tr >
                
< td >< Nature:MyFind  id ="ctl_CommonFind"  runat ="server" /></ td >
                
< td  width ="50" >
                    
< asp:Button  ID ="Btn_Search"  runat ="server"  Text =" 查 询 "   />
                
</ td >
            
</ tr >
        
</ table >
    
</ fieldset >
    
</ div >
    
< div >
        
< Nature:MyGrid  ID ="ctl_CommonGrid"  runat ="server"   />
    
</ div >
    
< div >
        
< Nature:QuickPager  ID ="ctl_CommonPager"  runat ="server"  PageUIGO ="GO"   />
    
</ div >
    
< span  id ="dd" ></ span >
    
< span  style ="DISPLAY:none" >
         
< asp:button  id ="Btn_ToExcel"  runat ="server"  Text ="导出到Excel"  onclick ="Btn_ToExcel_Click" ></ asp:button >
        
< asp:button  id ="Btn_ToAccess"  runat ="server"  Text ="导出到Access" ></ asp:button >
        
< asp:button  id ="Btn_Reload"  runat ="server"  Text ="刷新本页"  onclick ="Btn_Reload_Click" ></ asp:button >
        
< asp:button  id ="Btn_ReloadFirst"  runat ="server"  Text ="刷新到第一页"  onclick ="Btn_ReloadFirst_Click" ></ asp:button >
        
< Nature:MyTextBox  id ="Txt_isShowSearch"  runat ="server" />
        
< iframe  id ="ifrmDel"  name ="ifrmDel"  width ="100"  height ="100" ></ iframe >
    
</ span >
    
</ form >
</ body >


==========================
= 希望我的想法,能够给您带来一点帮助! =
= 大家一起研究、讨论,共同提高、发财! =
==========================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自己动手做框架是一种非常有挑战性的任务,尤其是对于 ORM(对象关系映射)、MVC(模型-视图-控制器)和IOC(控制反转)这三个框架而言。以下是对这三个框架的简要介绍,以及它们的实现过程。 首先,ORM(对象关系映射)框架是用于将数据库中的表映射为对象的一种技术。在实现ORM框架时,需要定义对象和表之间的映射关系,并提供相应的API来进行数据库的增删改查操作。还需要处理对象之间的关联关系(如一对一、一对多等),并提供事务管理、缓存等功能。 其次,MVC(模型-视图-控制器)框架是一种用于开发Web应用程序的架构模式,将应用程序分为模型、视图和控制器三层。在实现MVC框架时,需要定义模型、视图和控制器的接口,并提供相应的实现。模型负责处理数据逻辑,视图负责展示用户界面,而控制器则负责接收用户请求并进行处理,最后将结果返回给视图进行展示。 最后,IOC(控制反转)框架是一种通过依赖注入来管理对象之间的依赖关系的技术。在实现IOC框架时,需要定义依赖注入的规则,并提供相应的实现。可以使用反射机制来自动实例化对象,并将依赖的对象注入到目标对象中。还需要提供对象的生命周期管理(如单例模式、原型模式等)和对象的配置方式(如XML配置、注解配置等)。 总结来说,自己动手实现ORM、MVC和IOC框架需要掌握相关的技术和知识,并具备良好的设计和编码能力。除了理论知识外,还需要具备实际项目的经验,以便能够更好地设计和实现这些框架。同时,也需要不断学习和改进,跟上技术的发展潮流,以确保框架的高效和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值