通常在程序编程中我们所说的三层架构是指:显示层(UI)、逻辑层(BLL)和数据訪问层(DAL)。对于这三层来说,分工明白,各自有各自负责的领域。
UI层:1、负责向用户显示数据 2.负责採集用户输入的信息
BLL层:1.从DAL获取数据。以供UI显示 2.从UI中获取指令或数据。经业务逻辑送达到DAL
DAL层:1.主要用于对数据源的增删改查的操作。
通过它们各自负责的领域我们能够看出。BLL层属于中间层。它负责UI和DAL层之间的通信。那么通常我们还会增加一个实体层(Enity):主要负责返回实体,在上述三层之间传递參数。
那么为什么要划分三层呢?
通过划分三层。能够使得各部分功能非常好的被封装在一个包中。各自负责各自的功能,互不打搅。这符合面向对象封装的思想。
使得各个模块之间达到高内聚、低耦合。以至于一个部分的更换或改动不至于影响到整个项目的实施进程。
那么这三层之间是怎样进行通信的呢?
UI层引用BLL层。BLL层引用DAL层,它们三者同一时候都引用Enity。
但是,为什么不能循环引用(BLL引用UI,DAL引用BLL,DAL引用UI)呢?事实上这就是回到了为什么要分三层,分三层是为了封装。假设继续循环引用,那么就跟分三层没有不论什么差别。各个參数和数据随便传递,没有界限。
在这里,我们要知道Enity是用来供三层之间相互通信。传递数据的。可是基于三层封装的思想,三层在传递參数时,传递的应该是一个实体。而不是实体中的某个參数。这个符合设计模式中的依赖倒转原则,依赖抽象而不依赖细节,事实上也就是封装。
为了更清楚理解上述的这些知识。
我用VB.NET做了一个三层关于登录的一个小样例:
Enity层:将程序中所要传递的參数进行声明
Public Class LoginEnity ''' <summary> ''' 用户ID ''' </summary> ''' <remarks></remarks> Private User_ID As Integer Public Property UserID() As String Set(value As String) User_ID = value End Set Get Return User_ID End Get End Property ''' <summary> ''' username ''' </summary> ''' <remarks></remarks> Private User_Name As String Public Property UserName() As String Set(value As String) User_Name = value End Set Get Return User_Name End Get End Property ''' <summary> ''' 用户password ''' </summary> ''' <remarks></remarks> Private _pwd As String Public Property Password() Set(value) _pwd = value End Set Get Return _pwd End Get End Property End Class
UI层:引用BLL的业务逻辑进行显示数据
Private Sub ButLogin_Click(sender As Object, e As EventArgs) Handles ButLogin.Click Dim user As New Enity.LoginEnity '实例化实体 user.UserName = txtUserName.Text user.Password = txtPassword.Text Dim managerBLL = New BLL.LoginBLL 'UI层引用BLL层 If managerBLL.UserIsExist(user) = True Then '利用BLL层中的函数进行逻辑推断 frmQuery.Show() Else MessageBox.Show("登录失败!") End If End Sub
BLL层:引用DAL进行逻辑推断
Public Function UserIsExist(ByVal user As Enity.LoginEnity) As Boolean '注意这里传递的为一个实体。而不是详细的某个參数 Dim manager As New DAL.LoginDAL '引用DAL层。进行实例化 Dim Euser As New Enity.LoginEnity '引用实体层 Try Euser = manager.UserIsExist(user) '利用DAL中的函数进行验证 If user.UserName = Euser.UserName And user.Password = Euser.Password Then'进行逻辑推断 Return True Else Return False End If Catch ex As Exception '对DAL层中抛出的错误进行错误处理 Return False End Try End Function
DAL层:主要负责对数据源中数据的增删改查等操作。
Public Function UserIsExist(ByVal user As Enity.LoginEnity) As Enity.LoginEnity ’參数传递为实体 '进行数据库连接相关代码的编写 Dim sqlConn = New SqlConnection(DbUtil.strConn) Dim cmdText As String = "select UserName,Password from User_Login where UserName=@UserName and Password=@Password" Dim cmd As New SqlCommand(cmdText, sqlConn) '加入參数 cmd.Parameters.Add(New SqlParameter("@UserName", user.UserName)) cmd.Parameters.Add(New SqlParameter("@Password", user.Password)) Dim reader As SqlDataReader sqlConn.Open() '打开数据连接 reader = cmd.ExecuteReader() '从数据库中读取数据 If (Not user Is Nothing) Then If reader.Read() Then user.UserName = reader.Item("UserName")'与数据源中的数据进行验证。是否一致 user.Password = reader.Item("Password") Else Throw New System.Exception("无记录!") '若不存在此条记录。抛出错误 End If End If Return user sqlConn.Close() '关闭连接 cmd = Nothing End Function
通过以上的小样例,我们能够看出,事实上每个小样例都能够由UI、BLL和DAL这三层构成。
而实体层则负责数据传递,它将各个层连接成了一条线。从这样的角度讲,每个程序都是有若干条类似的线组成的。
小结:所谓三层架构,基于面向对象的思想。事实上能够看做一种非经常常使用的设计模式。只是这个设计模式是作用于整个程序的一个框架设计,它的应用更加普遍。更加宏观。
而我们通常学习的设计模式则是针对于于代码中详细某个业务或是某个领域,它针对的是更加细节的地方。
而三层框架的设计和设计模式的共同应用才构成了我们灵活多变的程序设计。