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



    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="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>


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

  • 相关阅读:
    iOS 地图与定位开发系列教程(一)
    opencv 之 transformation
    the brain 8.0
    vs中添加库文件WinMM.Lib
    JAVA简单性能检测
    【转帖】一套鼠标控制2台电脑
    Synergy工具一套键盘鼠标连接多台机器
    文件夹下所有文件及子文件夹将文件名小写
    捕捉Facebook Like的数据
    按键精灵的网页自动化测试
  • 原文地址:https://www.cnblogs.com/jyk/p/1564540.html
Copyright © 2020-2023  润新知