zoukankan      html  css  js  c++  java
  • 【自然框架】用CMS的栏目举例,聊一聊从“一层”到“三层”的变化


      做CMS最基本的一个功能就是做一个栏目导航,如果这个导航想做成动态的(即需要从数据库里提取数据)那么要如何实现呢?

    简单的方法——DataTable


     

      一个表两个字段,把数据提取出来,放在DataTable里面,然后在页面里做一个循环,OK了。是不是很简单呢?如果看了我的代码,估计会有很多人提出异议,呵呵。这里就是想和大家详细讨论一下。

      由于每个页面都要用导航,而且都是一样的,所以我建立一个UserControl(用户控件)来做这个导航。首先在.ascx页面里定义一个protected的DataTable。然后在Page_Load里面填充这个DataTable。三行代码搞定。

    【代码】

    代码
    protected DataTable dtChannel;

    protected void Page_Load(object sender, EventArgs e)
    {
        DataAccessLibrary dal 
    = DALFactory.CreateDAL();
        dtChannel 
    = dal.ExecuteFillDataTable("SELECT channelName, URL FROM CMS_Channel ORDER BY Sort ");
        dal.Dispose();
    }

      再看页面部分。

    <%foreach (DataRow dr in dtChannel.Rows )
    %>
          
    <td><class="t1" href="<%=dr[1].ToString() %>"><%=dr[0].ToString() %></a></td>
    <%%>

      遍历一遍就可以了。如果您不喜欢Table的话,那么换成DIV也行,对于遍历来说是没什么区别的。

      好了,搞定。下面开始讨论您的疑问。

      1、 在页面里出现了SQL语句,这个是不对的,即使是在.aspx.cs里面也是不行的。

      2、 用DataTable是不好的,要用实体类。

      3、 dr[1].ToString()。这种写法是不明确、不易读的,谁知道“1”代表什么意思?

      我这里并不是为自己辩解,只是想说一下我的想法。说一下我的想法总是可以的吧?

      1、 对于栏目这个特定的问题来说,表名和字段名都是比较稳定的,变动的可能性不大,即使变动了,这个SQL语句里面也只出现了两个字段名和一个表名,变化了,改就行了。由于用了UserControl,和栏目数据库相关的都放在这里,所以改一处就可以了。

      2、 只有两个字段,就要定义一个实体类?我觉得有点浪费。也许您觉得DataTable性能不如实体类。这个我一直没做过测试,不知道他们到底差了多少。在数据量大和数据量少的时候,都差了多少。有空的话,我也想做一下这个测试。就栏目来说,我觉得专门定义一个实体类,实在是太浪费了。

      3、 dr[1] 。这个是从效率和预防变更的角度来考虑的。这个比用字段名要快一些,而且字段名字变更了,这个也是不用改的。这里只有两个字段,虽然1、0不易读,但是数量少,也可以勉强接受了。


     

      小结,这种写法的结构如下:

      

      看着有点复杂,其实还是那几行代码。数据库就不用说了,ADO.net是系统提供的,不用我们操心,数据访问函数库是我自己写的,都封装好了,编译成DLL直接引用调用就可以了,剩下的就是页面了。就是那几行代码。

      当然,您可以说我这是狡辩,也可以说我是老顽固,呵呵。不过请先别着急写回复,请先看完整了,在回复也不迟。对吧。

    两层
     

      上面的写法只是针对个别的情况,表名、字段名比较稳定,字段数量少,只有一个地方使用的情况。其他情况确实就不太适合了。那么要怎么改呢?我们试着往“三层”的方向修改一下。

      我们建立一个项目,作为“业务逻辑层”。在建立一个.cs文件,里面定义一个类,在加一个函数,在这个函数内些三行代码,就是上面.ascx.cs里面的那三行。而.ascx.cs里面就可以改成调用这个类的方式了。

      这样就可以了吗?也不对呀,业务逻辑层里面同样不可以写SQL语句的。还有,这个类是写成静态的,还是非静态的?如果还有其他的类似的需求,那么是写到一个.cs文件里面,还是写到多个.cs文件里面。就是说这个类独占一个.cs文件,还是和其他的类放在同一个.cs文件里面?疑惑呀,不知道到底怎么写了。

      小结:加入了一个业务逻辑层,结构如下:

     

    三层


      业务逻辑里面不让写SQL,那么就在建立一个项目,作为数据层,在建立一个.cs文件,在定义一个类,在写一个函数,把上面那三行拿过来,原先的地方在改成调用这个函数。

      这回可以了吧,数据层里面是可以写SQL语句的。也是三层了,三个项目了呀,一层一层往下调用。

      但是回过头来看看,页面里调用一个类,得到了DataTable,这个是简洁了,但是业务逻辑层呢?一个类,一个函数,一行调用的代码,整个一个传声筒。数据层,虽然有三行代码,但是有效地就是那个SQL语句。如果数据库有变动,还是要修改,虽然不用满世界找SQL语句了,只在这个数据层里面找就可以,但是针对这个具体的问题,这么做有什么优势呢?

      也许您会说,我这个根本就不是三层!不是说做了三个项目,把原来放在一起的代码分别放在了三个地方就是三层了。恩,我也觉得不是。三层怎么可能是这样?

    但是真正的三层又是什么样子呢?真的很是不清楚。

      这些是我的思考过程,拿出来和大家讨论一下,如果只有我一个人是这么写的,这么写代码的,那么我向大家道歉:多不住大家,占用了大家宝贵的时间,看这么无聊的贴子。

      如果还有人也是有类似的想法,或者对三层很迷茫,那么请各位高手帮帮忙,针对这个具体的问题,讲一讲用三层要怎么写代码。哦,对了,我很穷,如果您要收费的话,那我还是迷茫吧。

      小结:现在的结构。

    实体

      上面一直是用DataTable的,是不是要换成实体类呢?换成实体类就是三层了吗?就是面向对象了吗?同样,没那么简单吧。
    实体类是做什么的呢?仅仅是传递数据的吗?太浪费了吧。


    更换数据库

      三层的一个目的是要应对数据库的变化,如果数据库变更了,那么只需要修改(或者是改一下标记)数据层就可以了,其他的地方不用改。
    要应对各种数据库,就要定义一个接口,然后各个数据层实现不同数据库的访问方式。

      那么针对这个具体的问题我们来看看,请教一下,这个SQL语句在哪种关系型数据库里不能运行,或者是得到的结果不一致呢?应该是没有吧。那么还有必要为这个功能而设计一个接口在分别实现吗?

    有没有必要?什么情况下适合?要不要统一?

      终于到了最后一个问题了。说了半天,我都是针对这一个具体的问题来说的,您会说这个具体的问题太简单了,根本用不着三层。但是那么复杂的就需要了。另外从整体的角度来说,一个项目、一个产品,甚至一个公司,都应该有一个统一的方式,不能一个页面一层,另一个页面三层,这样不就乱了吗?你让新人怎么看?这个确实是个问题,自己写倒是可以清楚,哪些地方是什么形式的,但是对于其他人来说就头晕了,到底是什么形式呀?

      那么就要统一吗?即使对于个别情况,并不是适合的,但是也要配合大局、符合整体设计?一直都是以自己的方式来写项目,也不知道其他人是怎么做的。

      解决方向只有一个吗?肯定不是的,还有其他很多解决方向。只是都是非主流而已。

      还是不会写结尾,那么就以一个问题来结尾吧。

      请问,针对这个具体的问题要如何解决?一层?三层?还是其他的什么方式?

      也许是不能孤立的看问题,要从整体来看?从整体看才可以?


     

  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/jyk/p/1722866.html
Copyright © 2011-2022 走看看