机房重构开始有一段时间了,实现了三层登录以后,又开始与七层登录作斗争,每天面对着能够勉勉强强运行起来的可怜巴巴的窗体,还是感觉,理清了思路,明白了原理才是正道!
首先看一下我的包图。
说是七层,其实是八层,说到底还是三层。所谓七层,不过是在三层的基础上加了设计模式演化而来。七层分别是哪七层呢?即在三层的基础上加了外观层(Facade)、工厂层(Factory)和接口层(IDAL)。SqlHelper我们在下一篇博客里面会详细论述。
首先看一下我的界面,很大众化的……
首先看一下实体层的代码。
Private _userName As String Private _passWord As String Private _userLevel As String Private _userID As String 'UserName属性 Public Property UserName() As Integer Get Return _userName End Get Set(value As Integer) _userName = value End Set End Property 'Password属性 Public Property Password As String Get Return _passWord End Get Set(value As String) _passWord = value End Set End Property 'UserLevel属性 Public Property Level As String Get Return _userLevel End Get Set(value As String) _userLevel = value End Set End Property实体层,是最容易的了吧。我们在学习三层的时候都已经烂熟于心了。
再来看UI层。
'定义一个新的登陆实体 Dim facade As New Facade.LoginFacade Dim myList As New List(Of Entity.LoginEntity) Dim enUser As New Entity.LoginEntity Dim flag As New List(Of Entity.WorklogEntity) If txtUserName.Text = "" Then MsgBox("请输入用户名!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If If IsNumeric(txtUserName.Text) = False Then MsgBox("用户名请输入数字!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtUserName.Text = "" End If If txtPassword.Text = "" Then MsgBox("请输入密码!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If Try enUser.UserName = txtUserName.Text.Trim() enUser.Password = txtPassword.Text.Trim() myList = facade.SelectUser(enUser) If myList.Count > 0 Then MsgBox("登陆成功") '更新Worklog Dim enWorklog As New Entity.WorklogEntity enWorklog.UserName = txtUserName.Text.Trim() enWorklog.LoginDate = CStr(Format(Now(), "yyyy-MM-dd")) enWorklog.LoginTime = CStr(Format(Now(), "HH:mm:ss")) enWorklog.Status = "正在值班" enWorklog.Computer = Environment.GetEnvironmentVariable("USERNAME") flag = facade.AddWorklog(enWorklog) enLogin.UserName = myList.Item(0).UserName enLogin.Level = myList.Item(0).Level frmMain.Show() Me.Hide() End If Catch ex As Exception MsgBox(ex.Message.ToString()) txtUserName.Focus() txtUserName.SelectAll() txtPassword.Text = "" End TryUI负责与用户交互,负责数据的输入和输出,首先对输入的数据进行初步判定,符合UI的要求后,调用外观层的方法进行验证用户名和密码。
再来看我们先增的外观层(Facade)。
Public Function SelectUser(ByVal enUser As Entity.LoginEntity) As List(Of Entity.LoginEntity) Dim userBLL As New BLL.LoginBLL Dim myList As List(Of Entity.LoginEntity) myList = userBLL.SelectUser(enUser) If myList.Count = 0 Then Throw New Exception("用户名或密码错误") Else Return myList End If End Function外观层,说白了就是对方法的封装,就比如上述代码,封装了对于用户和密码的判定的方法。但是归根结底外观层调用的仍是B层的方法。它的作用其实不大。
Public Function SelectUser(ByVal enUser As Entity.LoginEntity) As List(Of Entity.LoginEntity) Dim factory As New Factory.LoginFactory Dim IUser As IDAL.IUser Dim myList As List(Of Entity.LoginEntity) IUser = factory.CreateIUser() myList = IUser.SelectUser(enUser) Return myList End Function返回数据给外观层验证用户名和密码是否正确,通过工厂层(Factory)和接口层(IDAL)验证方法。首先定义并实例化工厂,然后定义接口变量,通过List存储D层查询到的数据。
用反射加配置文件,防止更换数据库。
Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("strDB") '用户工厂 Public Function CreateIUser() As IDAL.IUser 'CType是一个内联函数,将前部分的表达式转换为后面的类型 Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & "LoginDAL"), IUser) '返回IuserinfoDAL End Function工厂的作用是创建接口,对于访问数据库相同的表提供一个统一的接口。
再看看接口层。
Function SelectUser(ByVal enUser As Entity.LoginEntity) As List(Of Entity.LoginEntity)
最后看一下D层。
Public Function SelectUser(ByVal enUser As Entity.LoginEntity) As List(Of Entity.LoginEntity) Implements IUser.SelectUser Dim strText As String = "select * from Login where UserName=@UserName and Password=@Password " Dim cmdType As CommandType = CommandType.Text Dim Parameter As SqlParameter() Parameter = {New SqlParameter("@UserName", enUser.UserName), New SqlParameter("@Password", enUser.Password)} Dim SqlHelper As New Sqlhelper.SqlHelper() Dim dt As New DataTable Dim myList As List(Of Entity.LoginEntity) dt = SqlHelper.ExecuteReaderTable(strText, cmdType, Parameter) myList = ConvertHelper.convertToList(Of Entity.LoginEntity)(dt) Return myList
最后的最后,我们把BLL,Factory,和IDAL三者的关系梳理一下。
BLL通过Factory创建接口,BLL使用接口,DAL实现接口。