一层还是三层?什么时候三层,什么时候不三层?
做网站最基本的一个功能就是做一个栏目导航,如果这个导航想做成动态的(即需要从数据库里提取数据)那么要如何实现呢?
简单的方法——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语句在哪种关系型数据库里不能运行,或者是得到的结果不一致呢?应该是没有吧。那么还有必要为这个功能而设计一个接口在分别实现吗?
有没有必要?什么情况下适合?要不要统一?
终于到了最后一个问题了。说了半天,我都是针对这一个具体的问题来说的,您会说这个具体的问题太简单了,根本用不着三层。但是那么复杂的就需要了。另外从整体的角度来说,一个项目、一个产品,甚至一个公司,都应该有一个统一的方式,不能一个页面一层,另一个页面三层,这样不就乱了吗?你让新人怎么看?这个确实是个问题,自己写倒是可以清楚,哪些地方是什么形式的,但是对于其他人来说就头晕了,到底是什么形式呀?
那么就要统一吗?即使对于个别情况,并不是适合的,但是也要配合大局、符合整体设计?一直都是以自己的方式来写项目,也不知道其他人是怎么做的。
解决方向只有一个吗?肯定不是的,还有其他很多解决方向。只是都是非主流而已。
还是不会写结尾,那么就以一个问题来结尾吧。
请问,针对这个具体的问题要如何解决?一层?三层?还是其他的什么方式?
也许是不能孤立的看问题,要从整体来看?从整体看才可以?
这里排版不大方便,如果您感兴趣的话,可以到我的博客里看看,另外还有一些讨论。http://www.cnblogs.com/jyk/archive/2010/04/28/1722866.html
[解决办法]
个人理解:
1〉业务规模越大,越有必要分层。
2〉越注重后期扩展,越有必要分层。
[解决办法]
如果是做一个小网站的话 不考虑后期的话 可以不用分成
但是做一个系统 业务和代码量 和数据库交互 量大的话 最好是分层次 好一些..
一层的话 代码毕竟都写在里面 要改起来的话 比较费劲
自己写的话 还好 要是别人来改你的代码的话 那就昏了,..!
[解决办法]
http://topic.csdn.net/u/20070315/10/4082706a-3b35-4abb-bbce-c9972953193c.html
时间真是快啊 ~ 一晃三年过去了
我在上面帖子回复时 还只是菜鸟 , 只了解一点面向对象的皮毛
但到是非常愿意与人谈论 OO ,以为自己懂的不少,实则贻笑大方。
反观现在 , 对面向对象的理解较之前深入不少, 但却很少与人谈论OO 了
原因很简单, 思维方式不一样, 你不能把自己的思维方式强加灌输在别人身上 ,
只能说是仅供参考。 分层也是如此,没有万能的, 合适的才是正确的, 但要保证程序的稳定性和维护性。
何必一定要执着于三层 或 N 层呢, 如果你真的需要分层的时候 ,自然就会想清楚如何处理了。
[解决办法]
刚才未看你的贴子先看了评论所以就直接写“mark”了,看完你的帖子还是有话要说的:
我刚工作的时候接手了一个OA,整个OA的写法就是楼主所说的两层写法,后台写SQL语句,调用已经写好的一个数据库访问类也就是楼主所说的数据库访问函数库,这样需求一变更,程序员只需要调整后台的SQL语句就搞定,后来项目升级,打着为了方便项目管理的口号,把原先的‘两层’弄成‘三层’,这一过程吃进了苦头,需求一变,程序员除了改界面和后台代码还要改数据层。
使用三层的优点:
1.作为项目管理来说,这样做十分规范,一个团队都是用这样的方式编程,以至于新人也能很快进入状态。否则代码会各有各的风格,我见过这样命名的 Dim i,ii,iii as integer
2.项目越来越多模块的时候,三层给你带来的好处就像潘多拉星球一样,到处都是接口,你想获取人员信息,就调用new BLL.Base_Employee().GetList(),想获取部门信息就调用new BLL.Base_Department().GetList(),这就是复用性,楼主你可以想象一下你想要什么数据就立马能获取什么数据的快感了。
3.当有一天,客户和你说:“大哥,我们老板决定将你们的软件由B/S换成C/S”,我不知道你考虑过没?
以上是我对三层的愚见,欢迎指正。
BLL层绝对不仅仅只是个传话筒,利用这一层你可以把缓存发挥得淋漓尽致,觉得麻烦就不写这层了。
至于用什么模式:其实客户并不关心过程,你的团队用什么方式顺手那就用吧,最后能舒服的做出项目来就行了。其实现在关于三层的代码生成器已经一大堆了,楼主你也可以针对你的团队写一个代码生成器,消减重复的工作量