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

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

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

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

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

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏灯塔大数据

每周学点大数据 | No.68 Hadoop 实践案例——等值连接

No.68 Hadoop 实践案例——等值连接 Mr. 王 :我们再来看看另一个非常常见的例子。很多时候,我们关心的数据来自多个表。比如在某学校的教务系统中,有...

432100
来自专栏令仔很忙

设计模式六大原则——迪米特法则(LoD)

   在图书馆借书,刚开始的时候,直接跑到相应的楼层去,到里面去转,去找要借的书,在里面溜达半天才能找到;后来知道图书馆有一个电脑查询处,然后直接在电脑上输入...

24810
来自专栏牛客网

c++后台开发实习面经 - 今日头条

4.tcp的三次握手四次挥手的全过程和状态,为什么要四次挥手,为什么要经过TIME WAIT状态

14030
来自专栏哲学驱动设计

OEA 扩展属性系统 - 主要设计类图

时间有限,简单快速的完成本篇博客……(很多问题在此就不细说清楚了,主要还是记录一下成果。) * 先是整个子系统要完成的需求列表: ? * 然后是对它的分析,以及...

27660
来自专栏云飞学编程

Python爬虫,抓取淘宝商品评论内容

作为一个资深吃货,网购各种零食是很频繁的,但是能否在浩瀚的商品库中找到合适的东西,就只能参考评论了!今天给大家分享用python做个抓取淘宝商品评论的小爬虫!

22740
来自专栏大数据和云计算技术

flink二三事(2):起家的技术

上一篇聊到flink的历史,请看上篇 flink两三事 ----(1)历史。 可以说基本上是起了个大早,赶了个晚集,但是flink能做今天这种热度,没有被spa...

48350
来自专栏程序员的碎碎念

redis不难,benny带你入门

关于redis的学习,相信在各大博客、公众号上和教学视频教程里有很多,benny学习了一段时间总算是入门了,在会不定期的更新redis学习日记。

13840
来自专栏GreenLeaves

EF基础知识小记一

1、EF等ORM解决方案出现的原因 因为软件开发中分析和解决问题的方法已经接近成熟,然后关系型数据库却没有,很多年来,数据依然是保存在表行列这样的模式里,所以,...

18290
来自专栏云技术

随机IOPS全面超越,腾讯云CSG 存储网关高性能缓存技术详解

CSG存储网关是基于腾讯云高性能、高可靠性的对象存储系统COS对外提供iSCSI、NFS和CIFS/SMB访问协议。作为一种混合云方案, 帮助用户不用修改本地应...

678170

Map-Reduce风格:数据感知vFabric GemFire中的分布式查询

大量快速的数据正在为当今市场上一些最有趣的计算机会提供动力。但想要达成目标,我们需要改变数据层的方法。企业正试图从昂贵的大型架构转向虚拟化数据中心,并更有效地利...

30360

扫码关注云+社区

领取腾讯云代金券