从三层到七层的转变确实是花费了不少的时间,不过收获也很大,咱们一起来看一下到底是怎么实现七层架构的。
首先,从宏观方面,我们来看一下,VS中七层架构的解决方案,让我们对七层有一个整体的认识。
这里我把SqlHelper放到了D层,当然,SQLHelper也可以单独拿出来,那样就变成了“八层”
那么问题又来了,这几层之间到底是什么关系呢?我们来看一下这几层之间的包图。
从图中我们可以看出,只有D层与接口之间是实现关系,其余各个包之间都是调用关系,有了包图,宏观上的代码也就有了。
U层:
U层界面:
U层代码:
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports Entity.LoginUserEntity '注入命名空间 Imports Facade Imports System.Net.Dns Public Class frmLogin Private Sub cmdOK_Click(sender As Object, e As EventArgs) Handles cmdOK.Click '非空判断 If txtUserID.Text = "" Then MessageBox.Show("请输入用户名!", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtUserID.Text = "" txtUserID.Focus() ElseIf txtPassWord.Text = "" Then MessageBox.Show("请输入密码!", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtPassWord.Text = "" txtPassWord.Focus() Exit Sub End If Dim FacadeLogin As New LoginFacade() '定义外观对象 Dim UserInfo As New Entity.LoginUserEntity() '定义实体对象 '将文本框中的输入内容传给实体 UserInfo.UserID = txtUserID.Text UserInfo.PassWord = txtPassWord.Text Dim strResult1 As Boolean strResult1 = FacadeLogin.CheckUser(UserInfo) '将U层的文本框的内容传入外观层,然后通过外观层传入B层进行判断,返回布尔值 If strResult1 = True Then frmHomePage.Show() Me.Hide() Else MsgBox("登录失败") End If End Sub</strong></span></span>
代码分析:从代码中我们可以看出,U层的作用是把用户的输入传给实体再传给外观层,代码虽然不少,但是核心代码只有一句FacadeLogin.CheckUser(UserInfo),将实体传给外观层并返回值。
外观层(Facade)
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports BLL Imports Entity Public Class LoginFacade Public Function CheckUser(ByVal UserInfo As Entity.LoginUserEntity) As Boolean Dim IsUserExists As New BLL.LoginBLL() 'new出B层对象 Dim Flag As Boolean Flag = IsUserExists.IsUserExists(UserInfo) '将实体传给B层并返回值 If Flag = True Then '存在返回true Return True Else Return False End If Return Flag End Function End Class </strong></span></span>
代码分析:登录的外观层很简单,只是单纯的将实体从U层传到B层,我个人觉得这个地方不用外观层也是可以的,因为外观层在这里的意义并不是很大。
B层:
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports Factory Imports IDAL Imports Entity Public Class LoginBLL '检查用户是否存在 Public Function IsUserExists(ByVal UserInfo As Entity.LoginUserEntity) As Boolean '定义接口 Dim Iuser As IDAL.IuserinfoDAL '调用工厂,创建接口 Iuser = Factory.LoginFactory.CreateUserInfo '定义接口对象,用于承接返回值 Dim table As New DataTable table = Iuser.SelectUser(UserInfo) '格局返回的条数,判断返回值 If table.Rows.Count > 0 Then Return True Else Return False End If End Function</strong></span></span>
代码分析:B层的作用是根据返回值判断此账户是否存在,我个人觉得B层是最麻烦的地方,因为它需要同时调用工厂和接口,逻辑上就会比其他层多一点点。B层没有直接调用D层,而是调用工厂和接口是为了解耦。、
接口(IDAL):
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports Entity Public Interface IuserinfoDAL '定义一个方法,检查用户是否存在 Function SelectUser(ByVal UserInfo As Entity.LoginUserEntity) As DataTable End Interfac</strong></span></span>
代码分析:接口的作用是定义一个判断账户是否存在的方法,B层和工厂都会调用接口,D层实现接口。这样分工明确,大大降低了B层和D层的耦合度。
工厂(Factory):
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports IDAL Imports System.Configuration '添加对配置文件的引用 Imports System.Reflection '添加对反射的应用 Public Class LoginFactory '读配置文件,D层的每个类都在配置文件里对应一个KEY '把KEY设置成变量,在下面的方法中只用这个变量就可以应用D层的类 Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBString") Public Shared Function CreateUserInfo() As IuserinfoDAL '返回IuserinfoDAL Return CType(Assembly.Load("DAL").CreateInstance("DAL.UserDAL"), IuserinfoDAL) '返回IuserinfoDAL End Function End Class</strong></span></span>
代码分析:工厂的作用工是创建接口对象,让接口对象去调用接口的方法。
D层:
<span style="font-size:18px;"><span style="font-size:24px;"><strong> Imports System.Data.SqlClient Imports Entity Imports IDAL Public Class UserDAL : Implements IDAL.IuserinfoDAL '实例化SqlHelper对象 Private SqlHelper As SqlHelper = New SqlHelper() Public Function SelectUser(UserInfo As LoginUserEntity) As DataTable Implements IuserinfoDAL.SelectUser Dim Sql As String Dim table As DataTable Dim sqlParams As SqlParameter() = {New SqlParameter("@UserID", UserInfo.UserID), '给参数赋值 New SqlParameter("@Password", UserInfo.PassWord)} Sql = "select * from T_User where UserID = @UserID and Pwd = @Password " '执行查询,返回table table = SqlHelper.ExecSelect(Sql, CommandType.Text, sqlParams) Return table End Function End Class</strong></span></span>
代码分析:D层要实现接口,具体的去执行判断账户是否存在。
七层登录只是一个开始,我这里的登录只是简单的返回了一个成功失败,没有具体的判断。最近我了解到登录是可以使用一个设计模式的——代理模式。这个我还没有具体是实现,有兴趣的同学可以试试。