深入浅出C#三层架构

 我来答
世纪网络17
2022-10-25 · TA获得超过5952个赞
知道小有建树答主
回答量:2426
采纳率:100%
帮助的人:143万
展开全部

  本文用一个示例来介绍如何建设一个三层架构的项目 并说明项目中各个文件所处的层次与作用 写本文的目的 不是为了说明自己的这个方法有多对 而是希望给那些初学三层架构却不知从何入手的朋友提供一点帮助 因为网上的文章 大多是注重理论的介绍 而忽略了具体的实践应用 或者有示例但讲得不透彻 导致看了之后 理论上又学习了一遍 但还是不知道代码怎么写 所以想从这个方面入手写一下 让从来没做过三层架构的初学者也能照猫画虎 写出代码来 文中的代码是伪代码 仅用来阐明思路

  正文

  一提三层架构 大家都知道是表现层(UI) 业务逻辑层(BLL)和数据访问层(DAL) 而且每层如何细分也都有很多的方法 但具体代码怎么写 到底那些文件算在哪一层 却是模模糊糊的 下面用一个简单的例子来带领大家实战三层架构的项目 这个例子只有一个功能 就是用户的简单管理

  首先建立一个空白解决方案 添加如下项目及文件

   添加ASP NET Web Application项目 命名为UI 新建Web Form类型文件User aspx(含User aspx cs)

   添加ClassLibrary项目 命名为BLL 新建Class类型文件UserBLL cs

   添加ClassLibrary项目 命名为DAL 新建Class类型文件UserDAL cs 添加SQLHelper引用 (这个是微软的数据访问类 也可以不用 直接编写所有的数据访问代码 我一般用自己写的数据访问类DataAccessHelper )

   添加ClassLibrary项目 命名为Model 新建Class类型文件UserModel cs

   添加ClassLibrary项目 命名为IDAL 新建Interface类型文件IUserDAL cs

   添加ClassLibrary项目 命名为ClassFactory

  相信大家已经看出来了 这个和Petshop的示例没什么区别 而且更简单 因为在下也是通过Petshop学习三层架构的 但一些朋友对于这几个项目所处的层次 以及它们之间的关系 可能比较模糊 这里逐个说明一下

   User aspx和User aspx cs

  这两个文件(以及文件所属的项目 下面也是如此 不再重复强调了)都属于表现层部分 User aspx比较好理解 因为它就是显示页面了 User aspx cs有些人觉得不应该算 而是要划到业务逻辑层中去 如果不做分层的话 那么让User aspx cs来处理业务逻辑 甚至操作数据库都没什么问题 但是做分层的话 这样就不应该了 在分层结构中 User aspx cs仅应该处理与显示有关的内容 其它部分都不应该涉及

  举例 我们实现用列表方式显示用户的功能 那么提取信息的工作是由BLL来做的 UI(本例中是User aspx cs)调用BLL得到UserInfo后 通过代码绑定到User aspx的数据控件上 就实现了列表的显示 在此过程中User aspx cs对UI没有起到什么作用 仅是用来传递数据 而且因为实际编码中大部分情况都是如此的实现 所以使有些人觉得User aspx cs不应该算UI 而应该并入BLL负责逻辑处理 继续往下看 这时提出了一个新需求 要求在每个用户的前面加一个图标 生动地表现出用户的性别 而且不满 岁的用儿童图标表示 这个需求的实现 就轮到User aspx cs来做了 这种情况下User aspx cs才算有了真正的用途

   NewBLL cs

  添加如下方法

  public IList<UserInfo> GetUsers() 返回所有的用户信息列表

  public UserInfo GetUser(int UserId) 返回指定用户的详细信息

  public bool AddUser(UserInfo User) 新增用户信息

  public bool ChangeUser(UserInfo User) 更新用户信息

  public void RemoveUser(int UserId) 移除用户信息

  此文件就属于业务逻辑层了 专门用来处理与业务逻辑有关的操作 可能有很多人觉得这一层唯一的用途 就是把表现层传过来的数据转发给数据层 这种情况确实很多 但这只能说明项目比较简单 或者项目本身与业务的关系结合的不紧密(比如当前比较流行的MIS) 所以造成业务层无事可做 只起到了一个转发的作用 但这不代表业务层可有可无 随着项目的增大 或者业务关系比较多 业务层就会体现出它的作用来了

  此处最可能造成错误的 就是把数据操作代码划在了业务逻辑层 而把数据库作为了数据访问层

  举例 有些朋友感觉BLL层意义不大 只是将DAL的数据提上来就转发给了UI 而未作任何处理 看一下这个例子

  BLL层

  SelectUser(UserInfo userInfo)根据传入的username或email得到用户详细信息

  IsExist(UserInfo userInfo)判断指定的username或email是否存在

  然后DAL也相应提供方法共BLL调用

  SelectUser(UserInfo userInfo)

  IsExist(UserInfo userInfo)

  这样BLL确实只起到了一个传递的作用

  但如果这样做

  BLL IsExist(Userinfo userinfo)

  {

  UerInfo user = DAL SelectUser(User)

  return (userInfo Id != null)

  }

  那么DAL就无需实现IsExist()方法了 BLL中也就有了逻辑处理的代码

   UserModel cs

  实体类 这个东西 大家可能觉得不好分层 包括我以前在内 是这样理解的 UI?àModel?àBLL?àModel?àDAL 如此则认为Model在各层之间起到了一个数据传输的桥梁作用 不过在这里 我们不是把事情想简单 而是想复杂了

  Model是什么?它什么也不是!它在三层架构中是可有可无的 它其实就是面向对象编程中最基本的东西 类 一个桌子是一个类 一条新闻也是一个类 int string doublie等也是类 它仅仅是一个类而已

  这样 Model在三层架构中的位置 和int string等变量的地位就一样了 没有其它的目的 仅用于数据的存储而已 只不过它存储的是复杂的数据 所以如果你的项目中对象都非常简单 那么不用Model而直接传递多个参数也能做成三层架构

  那为什么还要有Model呢 它的好处是什么呢 下面是思考一个问题时想到的 插在这里

  Model在各层参数传递时到底能起到做大的作用?

  在各层间传递参数时 可以这样

  AddUser(userId userName userPassword … )

  也可以这样

  AddUser(userInfo)

  这两种方法那个好呢 一目了然 肯定是第二种要好很多

  什么时候用普通变量类型(int string guid double)在各层之间传递参数 什么使用Model传递?下面几个方法

  SelectUser(int UserId)

  SelectUserByName(string username)

  SelectUserByName(string username string password)

  SelectUserByEmail(string email)

  SelectUserByEmail(string email string password)

  可以概括为

  SelectUser(userId)

  SelectUser(user)

  这里用user这个Model对象囊括了username password email这三个参数的四种组合模式 UserId其实也可以合并到user中 但项目中其它BLL都实现了带有id参数的接口 所以这里也保留这一项

  传入了userInfo 那如何处理呢 这个就需要按照先后的顺序了 有具体代码决定

  这里按这个顺序处理

  首先看是否同时具有username和password 然后看是否同时具有email和password 然后看是否有username 然后看是否有email 依次处理

  这样 如果以后增加一个新内容 会员卡(number) 则无需更改接口 只要在DAL的代码中增加对number的支持就行 然后前台增加会员卡一项内容的表现与处理即可

   UserDAL cs

  public IList<UserInfo> SelectUsers() 返回所有的用户信息列表

  public UserInfo SelectUser(int UserId) 返回指定用户的相信信息

  public bool InsertUser(UserInfo User) 新增用户信息

  public bool UpdateUser(UserInfo User) 更新用户信息

  public void DeleteUser(int UserId) 移除用户信息

  很多人最闹不清的就是数据访问层 到底那部分才算数据访问层呢?有些认为数据库就是数据访问层 这是对定义没有搞清楚 DAL是数据访问层而不是数据存储层 因此数据库不可能是这一层的 也有的把SQLHelper(或其同类作用的组件)作为数据访问层 它又是一个可有可无的东西 SQLHelper的作用是减少重复性编码 提高编码效率 因此如果我习惯在乎效率或使用一个非数据库的数据源时 可以丢弃SQLHelper 一个可以随意弃置的部分 又怎么能成为三层架构中的一层呢

  可以这样定义 与数据源操作有关的代码 就应该放在数据访问层中 属于数据访问层

   IUserDAL

  数据访问层接口 这又是一个可有可无的东西 因为Petshop中带了它和ClassFactory类工厂 所以有些项目不论需不需要支持多数据源 都把这两个东西做了进来 有的甚至不建ClassFactory而只建了IDAL 然后 IUserDAL iUserDal = new UserDAL() 不知意义何在 这就完全是画虎不成反类犬了

  许多人在这里有一个误解 那就是以为存在这样的关系 BLL?àIDAL?àDAL 认为IDAL起到了BLL和DAL之间的桥梁作用 BLL是通过IDAL来调用DAL的 但实际是即使你如此编码 IUserDAL iUserDal = ClassFacotry CreateUserDAL() 那么在执行 iUserDal SelectUsers() 时 其实还是执行的UserDAL实例 而不是IUserDAL实例 所以IDAL在三层中的位置是与DAL平级的关系

  通过上面的介绍 基本上将三层架构的层次结构说明了 其实 本人有一个判断三层架构是否标准的方法 那就是将三层中的任意一层完全替换 都不会对其它两层造成影响 这样的构造基本就符合三层标准了(虽然实现起来比较难^_^) 例如如果将项目从B/S改为C/S(或相反) 那么除了UI以外 BLL与DAL都不用改动 或者将SQLServer改为Oracle 只需替换SQLServerDAL到OracleDAL 无需其它操作等等 本来想在文中加入一些具体的代码的 但感觉不是很必要 如果大家觉得需要的话 我再补充吧

lishixinzhi/Article/program/net/201311/11365

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式