个人版机房重构正式开始有一段时间了,之前一直都是在用C#敲三层,刚开始转到.NET还有点不顺手呢,等敲了两条线感觉好多了。通过这次机房重构要在三层的基础上要加强对之前学习的设计模式的应用和练习,也算是学以致用了~~其中要用到抽象工厂、外观、模板等设计模式。今天主要来学习外观模式的应用。
要想应用外观模式之前,首先,我们先来了解一下什么是外观模式,它有什么好处,到底该怎么用?
外观模式,为子系统中的一组接口提供一个一致的界面。说白了就是用一个类将需要用到的多个子系统中的方法或属性封装到一起供外界使用,降低程序的耦合度。
例如,用户登录功能,用户登录时系统要先判断用户信息是否正确,如果正确那么需要在工作日志表中同时添加一条工作记录。而用户只是想登录并使用程序,根本不需要知道这些操作,这时我们就可以定义一个外观类:登录,将判断用户信息和添加工作日志的操作封装到一起,用户只根据发送的登录请求返回的信息进行相应的操作就可以了。如果还需要添加其他功能,同样的我们只需要在外观类中多封装一个方法就可以了,不用改变登录窗体。
再例如,充值功能,给一张卡充值,系统要先判断卡号是否已经注册,如果卡号确实存在,然后要更新卡的余额信息,同时还要在充值表中添加一条充值记录,用到了”增、改、查”三个操作,而用户对这些是不感兴趣的,他们只需要知道最后的结果就可以了,所以我们就可以用一个充值的外观类来封装所有的方法,所有的操作都在后台默默地执行最后返给用户一条结果就可以了。
好了,文字介绍了外观的功能,接下来我们看一下简单的代码实现吧~~以登录窗体来举例好了。。。
实体层:Entiry
一个实体类对应一张表,用户实体类如下,工作日志实体类同理,不再重复
<span style="font-size:18px;">Public Class En_UserInfo Private Shared _userID As Integer Public Shared _userName As String Public Shared _userLevel As String Public Shared _password As String Public Shared _head As Integer ''' <summary> ''' 设置和获得用户ID值 ''' </summary> ''' <value>用户ID</value> ''' <returns>用户ID</returns> ''' <remarks></remarks> Public Property UserID() As Integer Get Return _userID End Get Set(value As Integer) _userID = value End Set End Property Public Property UserName() As String Get Return _userName End Get Set(value As String) _userName = value End Set End Property Public Property UserLevel() As String Get Return _userLevel End Get Set(value As String) _userLevel = value End Set End Property Public Property PassWord() As String Get Return _password End Get Set(value As String) _password = value End Set End Property Public Property Head() As Integer Get Return _head End Get Set(value As Integer) _head = value End Set End Property End Class</span>
D层:
从用户表中查询用户信息判断输入的信息是否正确
<span style="font-size:18px;"><span style="font-size:18px;">Imports System.Data Imports System.Data.SqlClient Imports Entity Imports SqlHelper Imports IDAL Public Class UserDAO : Implements IDAL.IUserInfo Dim dt As New DataTable Dim sqlhelper As New Global.SqlHelper.SqlHelper Dim flag As Boolean ''' <summary> ''' 根据ID号得到用户信息 ''' </summary> ''' <param name="user"></param> ''' <returns>datatable</returns> ''' <remarks></remarks> Public Function GetUserInfo(ByVal user As En_UserInfo) As DataTable Implements IUserInfo.GetUserInfo Dim sql As String = "select * from user_table where userID=@UserID" '查询语句 Dim paras As SqlParameter() = {New SqlParameter("@UserID", user.UserID)} '添加参数 dt = sqlhelper.ExecSelect(sql, CommandType.Text, paras) Return dt End Function</span></span>
往工作日志表中添加一条工作记录
<span style="font-size:18px;"><span style="font-size:18px;">Imports Entity Imports SqlHelper Imports IDAL Imports System.Data Imports System.Data.SqlClient Public Class WorkLogDAO : Implements IDAL.IWorkLogInfo Dim sqlhelper As New SqlHelper.SqlHelper Dim flag As Boolean Dim dt As New DataTable Dim sql As String Dim paras As SqlParameter() ''' <summary> ''' 添加工作日志记录 ''' </summary> ''' <param name="enworklog"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function AddWorkLog(enworklog As En_WorkInfo) As Object Implements IWorkLogInfo.AddWorkLog sql = "insert into worklog_table (userID,onDate,onTime,computerID) values (@userID,@onDate,@onTime,@compuerID)" paras = {New SqlParameter("@userID", enworklog.userID), New SqlParameter("@onDate", enworklog.onDate), New SqlParameter("@onTime", enworklog.onTime), New SqlParameter("@compuerID", enworklog.compuerID)} flag = sqlhelper.ExecAddDelUpdate(sql, CommandType.Text, paras) Return flag End Function</span></span>
B层
此处将外观层定义为一个类添加到了B层,定义外观类为F_Login。当然可以根据自己的需要,也可以把外观层以新项目的形式添加到总项目根目录下
<span style="font-size:18px;"><span style="font-size:18px;">Imports Entity Public Class F_Login '相当于外观模式中的"基金"类 Public bUserInfo As New UserBLL Public bWorkLog As New WorkLogBLL ''' <summary> ''' 相当于外观模式中基金的"买/卖"方法 ''' </summary> ''' <param name="enuser"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function Login(ByVal enuser As En_UserInfo, ByVal enworklog As En_WorkInfo) As String Dim result As String Dim dt As New DataTable Try result = bUserInfo.VerifyPassWord(enuser) Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示信息") End Try If result = "用户成功登陆" Then Try bWorkLog.AddWorkLog(enworklog) Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示信息") End Try End If Return result End Function End Class </span></span>
以下两段代码相当于子系统中的方法实现
<span style="font-size:18px;"><span style="font-size:18px;">Imports System.Data Imports System.Data.SqlClient Imports Entity Imports chargeDAL Imports IDAL Imports SqlFactory.sqlFactory Public Class UserBLL '创建工厂类,来创建接口对象 Public userfactory As New SqlFactory.sqlFactory Dim dt As New DataTable ''' <summary> ''' 判断用户是否已经存在 ''' </summary> ''' <param name="user"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function IsExist(ByVal user As En_UserInfo) As Boolean Dim Iselectuser As IDAL.IUserInfo Iselectuser = SqlFactory.sqlFactory.GetUserInfo Try dt = Iselectuser.GetUserInfo(user) Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示信息") End Try If dt.Rows.Count > 0 Then 'MsgBox("用户已经注册,不能重复注册") Return False '用户已经存在 Else Return True End If End Function ''' <summary> ''' 判断用户密码是否正确 ''' </summary> ''' <param name="enuser"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function VerifyPassWord(ByVal enuser As En_UserInfo) As String '创建获得用户信息的接口 Dim flag As String Dim IGetPwd As IDAL.IUserInfo Dim Iwork As IDAL.IWorkLogInfo IGetPwd = SqlFactory.sqlFactory.GetUserInfo dt = IGetPwd.GetUserInfo(enuser) If dt.Rows.Count = 0 Then '用户不存在 flag = "该用户不存在!" Return flag Else If enuser.PassWord = Trim(dt.Rows(0).Item(2)) Then flag = "用户成功登陆" '密码正确 Iwork = SqlFactory.sqlFactory.GetWorkInfo Else flag = "密码错误,请重新输入!" End If Return flag End If End Function</span></span>***********************************************************************************************************************************************************************************************************************************************************************
<span style="font-size:18px;"><span style="font-size:18px;">Imports Entity Imports SqlFactory Imports IDAL Public Class WorkLogBLL ''' <summary> ''' 添加工作日志 ''' </summary> ''' <param name="enwork"></param> ''' <remarks></remarks> Public Sub AddWorkLog(ByVal enwork As En_WorkInfo) Dim Iaddworklog As IDAL.IWorkLogInfo Try Iaddworklog = SqlFactory.sqlFactory.GetWorkInfo Iaddworklog.AddWorkLog(enwork) Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示信息") End Try End Sub End Class</span></span>
U层:
<span style="font-size:18px;"><span style="font-size:18px;">Imports chargeManageBLL Imports Entity Public Class frmLogin ''' <summary> ''' 确定登录 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnOK.Click Dim blogin As New F_Login Dim enuser As New En_UserInfo '定义实体变量 Dim result As String '定义一个标识 Dim enworklog As New En_WorkInfo enuser.UserID = txtUserID.Text.Trim() enuser.PassWord = txtPwd.Text.Trim() enworklog.userID = txtUserID.Text enworklog.onDate = DateTime.Today.ToString("yyyy-MM-dd") enworklog.onTime = DateTime.Now.ToString("HH:mm") enworklog.compuerID = Environment.MachineName 'enworklog.offTime = "null" 'enworklog.offDate = "null" Try result = blogin.Login(enuser, enworklog) Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示信息") End Try If result = "用户成功登陆" Then frmMain.Show() Else txtUserID.Text = "" txtPwd.Text = "" txtUserID.SelectAll() txtUserID.Focus() End If End Sub</span></span>
刚开始的时候,每个功能都添加了外观模式,比如查询充值记录、添加充值记录等等,呵呵~~~~后来跟师父交流,其实并不是每个功能都需要用到外观模式的,例如上面提到的添加充值记录,本来就是一个简单的功能,如果在加上外观模式其实就起反作用了,一两个还好,要是整个程序下来反而事倍功半,增加了程序的复杂度,在程序实现过程中确实有这种体会。所以说东西好也不可以无节制、无选择的使用。
编程在继续,经验在积累,如有不同看法或者更好的理解欢迎来交流~~~~