【自然框架】用CMS的栏目举例,聊一聊从“一层”到“三层”的变化

简介:   做CMS最基本的一个功能就是做一个栏目导航,如果这个导航想做成动态的(即需要从数据库里提取数据)那么要如何实现呢?   简单的方法——DataTable     一个表两个字段,把数据提取出来,放在DataTable里面,然后在页面里做一个循环,OK了。


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

 

简单的方法——DataTable


 

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

 

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

【代码】

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
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语句在哪种关系型数据库里不能运行,或者是得到的结果不一致呢?应该是没有吧。那么还有必要为这个功能而设计一个接口在分别实现吗?

 

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

 

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

 

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

 

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

 

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

 

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

 

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


 

相关文章
|
3月前
|
机器学习/深度学习 并行计算 算法
龚大视频学习笔记:上帝视角看GPU(2)-逻辑上的模块划分
龚大视频学习笔记:上帝视角看GPU(2)-逻辑上的模块划分
56 0
|
3月前
|
前端开发 搜索推荐 JavaScript
探析单页应用(SPA)与多页应用(MPA):从技术角度选择合适的应用形式
随着Web应用的快速发展,单页应用(SPA)和多页应用(MPA)成为了开发者们在构建Web应用时常遇到的两种选择。本文将从技术角度出发,深入比较单页应用和多页应用的特点和优势,帮助读者更好地选择适合自己项目的应用形式。
18 0
|
8月前
|
计算机视觉
队列的概念及结构(内有成型代码可供CV工程师参考)
队列的概念及结构(内有成型代码可供CV工程师参考)
55 0
|
9月前
|
前端开发 NoSQL Redis
项目实战典型案例5——发送调查问卷流程图例子(将不必要的逻辑放入前端)
项目实战典型案例5——发送调查问卷流程图例子(将不必要的逻辑放入前端)
79 0
|
10月前
|
前端开发
前端学习笔记202303学习笔记第五天-组件的三个组成部分 原
前端学习笔记202303学习笔记第五天-组件的三个组成部分 原
55 0
聊天框(番外篇)—如何实现@功能的整体删除
上一篇文章中,我们已经初步实现了聊天输入框,但其@功能是不完善的,例如无法整体删除、无法获取除用户名以外的数据(假设用户名不是唯一的)。有问题就要想办法解决,在网上百度了一圈后,倒是有一些收获。本文就着重解决@的整体删除以及获取额外数据。
956 0
聊天框(番外篇)—如何实现@功能的整体删除
|
前端开发
前端项目实战45-加一层判断 否则影响项目执行
前端项目实战45-加一层判断 否则影响项目执行
47 0
|
Android开发 UED iOS开发
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
|
开发者 容器
「站在上帝的角度」谈谈Element组件结构-InputNumber
「站在上帝的角度」谈谈Element组件结构-InputNumber
|
容器
「站在上帝的角度」谈谈Element组件结构-Rate
「站在上帝的角度」谈谈Element组件结构-Rate