日期:2008-09-11  浏览次数:20383 次

三层式开发中的层次划分讨论


先举一个曾经在哪本书上看到的例子:现在你想在1米宽的小溪上建一座桥,你会在上面放块木板就完了。如果想在宽一点的小河上建这桥,你就需要计算木材用料,价格等,如果需要别人帮忙,你还要多一些图纸什么的让别人理解你的想法。现在你要在大江上面建桥,你需要有整体的计划,包括各个方面,比如将来可能的收费和利益分配等问题。







这里讲3层式,其实是针对“大江上面建桥”来的,对于1米宽的小溪,在实际中可能一点用都没有。不过现在我不可能去拿个长江大桥作例子来讲,所以这里还是用这条简单的小溪,讲讲怎么建桥。之所以讲这么多废话,是为了防止部分人看完此文之后“小小一个东西,搞那么麻烦干什么。。”其实这里讲的不是具体的这个例子,而是分层的思想,理解这点非常重要。







下面我就我们大家日常见最多的例子来讲,就是“用户登录”的例子。这个例子很简单,但是麻雀虽小五脏俱全。从数据访问到业务规则到界面全有了。







本文分2个部分,如果只想研究面向对象的思想,对实现已经熟悉,可以跳过第一部分。






第一部分


 







新建一个空白解决方案。然后:







“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“数据访问”(数据层,下简称D层)







“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“业务规则”(业务层,下简称C层)







“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“Web用户界面”(界面层,下简称U层)







右键点“解决方案”-“项目依赖项”,设置U依赖于D、C,C依赖于D。







对U添加引用D、C,对C添加引用D。







到此为止,一个三层的架子建立起来了。我上面说的很具体很“傻瓜”,知道的人觉得我废话,其实我这段时间很强烈的感觉到非常多的人其实对这个简单的过程完全不了解。虽然不反对建2个“空项目”和1个“Asp net Web应用程序项目”也可以作为3层的框架,而且相当多的人认为其实这些“企业级模板项目”其实就是个空项目,这是一个误区。没错,企业级模板项目你从解决方案资源管理器里看它是个什么也没有的,但是你可以用记事本打开项目文件,看见不同了吧??有些东西在背后,你是看不见的,不过系统已经做好了。也就是说,如果你在C层里的某个类里“using System Data SqlClineit”,或者使用一个SqlConnection对象,编译时候不会出错,但是会在“任务列表”里生成一些“策略警告”,警告你在C层里不要放应该放在D层的东西(虽然就程序来说没错,但是可读性可维护性就打了折扣)而这种功能,空项目是无法給你的。







 







我们知道建桥需要砖块,应该是先准备好砖再来建桥,不过为了讲解上的顺序性和连贯性,简单性。我们先建桥,建的过程中需要砖块再现做,这样就不会多出来“桥不需要的东西”。注意在实际中,还是应该先准备砖块。







 







U层其实就是桥,C层是砖块,D层是原料(石头、沙子)。这也解释前面为什么U层要引用、依赖D层(而不是U对C,C对D的层次),因为桥除了需要砖头,其实也需要石头沙子。







我们在U层建一个Login aspx(这里插入一句,我不喜欢去把系统自动生成的WebForm1 aspx拿来改成login或index或直接删除,我一般留着它当测试代码用,等到整个系统冻结再把它移除就可以了。)添加1个TextBox(id=txt),一个DropDownList(id=ddl),一个Button(id=btn)。其中DropDownList用来选择用户名,button是提交按钮, TextBox用来输入密码。







现在我们必须要添加的代码分为2部分: 1、Page_load时对ddl的初始化。2、btn的click处理。







1:







private void Page_Load(object sender, System.EventArgs e)







{







if(!IsPostBack)







{







this.ddl.DataSourse=DataManager.GetOneColunm(“User”,”uid”); //讲解1







this.ddl.DataBind();







}







}







2:







private void Btn_Click(object sender, System.EventArgs e)







{







string uid=this.ddl.SelectedValue;







string psw=this.txt.Text;







if(psw =””)







     MessageBox(“空密码!”);







else







{







     User theUser;







     try







     {







          theUser=new User(uid); //讲解2







     }







     catch(Exception e)







     {







  MessageBox(e. Message);//讲解2







  return;







}







if(theUser.CheckPsw(psw)) //讲解3







{







  theUser.SetSessions();







  Response.Redirect(“……………..”);  //登录成功! 







}







else