刚敲完三层的小例子之后,感觉还是很简单的,只是通过分层让不同的层次完成不同的工作,减少耦合性。可是接下来师父就直接给了一个大难题,让我将三层转变为七层,这对我来说相当困难,自己当时根本就不知道有哪几层,就开始搜。经过一段时间的思考后,终于能够初步明白登录的七层是那些了。下面是我画的包图:
三层的时候只有UI、BLL、DAL,七层只是在原来基础上添加了外观设计模式、接口和抽象工厂,通过分层来减小耦合度。接下来如何来实现各层之间的链接呢?
U层:表示层,主要负责与界面设置。
Imports Facade '引入外观
Imports Entity '引入实体
Public Class frmLogin
Private Sub btnConfirm_Click(sender As Object, e As EventArgs) Handles btnConfirm.Click
If txtUserID.Text = "" Then
MessageBox.Show("请输入用户名")
txtUserID.Text = ""
txtUserID.Focus()
Exit Sub
ElseIf txtPassword.Text = "" Then
MessageBox.Show("请输入密码")
txtPassword.Text = ""
txtPassword.Focus()
Exit Sub
End If
Try
Dim facadeLogin As New Facade.LoginFacade
Dim User As New En_User
User.ID = txtUserID.Text.Trim()
User.Password = txtPassword.Text.Trim()
Dim flag As Boolean
flag = facadeLogin.CheckUser(User)
If flag = False Then
MsgBox("用户不存在")
txtUserID.Text = ""
txtPassword.Text = ""
txtUserID.Select()
txtUserID.Focus()
End If
Dim table As DataTable
table = facadeLogin.CheckPwd(User)
If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(1)) Then
MsgBox("登录成功")
txtUserID.Text = ""
txtPassword.Text = ""
End If
Catch
MsgBox("用户不存在或者密码不正确")
txtUserID.Text = ""
txtPassword.Text = ""
txtUserID.Select()
txtUserID.Focus()
End Try
End Sub
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Close()
End Sub
End Class
Facade层:这一层采用外观模式,通过外观模式使U层不直接和BLL层接触,减少B层和U层之间的耦合,当然这样做现在看起来好像有点繁琐,使我们本来简单的系统复杂化,但在大项目中能够体现其优越性。
Imports BLL '引用BLL层
Imports Entity '引用实体
Public Class LoginFacade
Public Function CheckUser(ByVal User As En_User) As Boolean
'用于检查用户是否存在
Dim IsUserExists As New BLL.LoginBLL()
Dim flag As Boolean
flag = IsUserExists.IsUserExits(User)
If flag = True Then
Return True
Else
Return False
End If
End Function
'检查密码是否正确
Public Function CheckPwd(ByVal User As En_User) As DataTable
Dim IsPwd As New BLL.LoginBLL()
Dim table As DataTable
table = IsPwd.isPWDright(User)
Return table
End Function
End Class
BLL层:接下里就将值传给B层,交由其处理,BLL层主要对业务逻辑进行管理,相当于就是对一个业务的处理。比如登录你就需要验证用户是否存在,密码是否正确,这一层将分开的功能组合到一块来完成一个业务。
Imports IDAL '引用IDAL
Imports Factory '引用Factory
Imports Entity '应用实体
Public Class LoginBLL
Public Function IsUserExits(ByVal User As En_User) As Boolean
Dim factory As New DateAccess
Dim IUser As IUserLogin
'调用创建用户的工厂方法
IUser = factory.CreateUser
Dim table As DataTable
Dim flag As Boolean
table = IUser.CheckUser(User)
If table.Rows.Count > 0 Then
flag = True
Else
flag = False
End If
Return flag
End Function
Public Function IsPWDright(ByVal User As En_User) As DataTable
Dim factory As New DateAccess
Dim Iuser As IDAL.IUserLogin
Dim table As DataTable
Iuser = factory.CreateUser
table = Iuser.CheckUser(User)
Return table
End Function
End Class
Factory层:抽象工厂+反射+配置文件
Imports IDAL '引入IDAL
Imports System.Configuration '引入配置文件
Imports System.Reflection
Public Class DateAccess
Private Shared ReadOnly paceName As String = "DAL"
Private Shared ReadOnly db As String = ConfigurationManager.AppSettings("<span style="color:#ff0000;">DB</span>")
Public Function CreateUser() As IUserLogin
Dim className As String = paceName + "." + db + "LoginDAL"
Dim iuser As IDAL.IUserLogin
iuser = CType(Assembly.Load(paceName).CreateInstance(className), IUserLogin)
Return iuser
End Function
End Class
配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key ="<span style="color:#ff0000;">DB</span>" value ="Sql"></add>
<add key ="ConnString" value ="Server=.;DataBase=Login;User ID =sa;Password =1"/>
</appSettings>
</configuration>标注红字的部分一定要对应,否则就会出现问题。
IDAL层:也就是接口层,实现和DAL层的连接,接口达到了统一访问的目的,另外通过接口方便DAL层的工作分配。
Imports Entity '引用实体
Public Interface IUserLogin
Function CheckUser(ByVal enuser As En_User) As DataTable
End InterfaceDAL层:主要是用来对表进行操作,通过SQL Helper来和数据库连接。
Imports Entity
Imports System.Data
Imports System.Data.SqlClient
Public Class SqlLoginDAL : Implements IDAL.IUserLogin
Public Function UserLoginDAL(ByVal enuser As En_User) As DataTable Implements IDAL.IUserLogin.CheckUser
Dim cmdText As String = "select * from Users where ID=@userID"
Dim sqlparams As SqlParameter() = {New SqlParameter("@userID", enuser.ID)}
Dim helper As New sqlHelper<span style="white-space:pre"> </span>'用于连接数据库
Dim table As New DataTable
table = helper.ExecSelect(cmdText, CommandType.Text, sqlparams)
Return table<span style="white-space:pre"> </span>'返回记录
End Function
End Class
通过将登陆由三层转变为七层,对与变量之间的传递和调用关系理解的更清楚了,虽然还有一些欠缺,相信在接下来的机房重构中,会理解的更加深刻。。。