重构个人版机房收费系统——外观模式

       个人版机房重构正式开始有一段时间了,之前一直都是在用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>

       刚开始的时候,每个功能都添加了外观模式,比如查询充值记录、添加充值记录等等,呵呵~~~~后来跟师父交流,其实并不是每个功能都需要用到外观模式的,例如上面提到的添加充值记录,本来就是一个简单的功能,如果在加上外观模式其实就起反作用了,一两个还好,要是整个程序下来反而事倍功半,增加了程序的复杂度,在程序实现过程中确实有这种体会。所以说东西好也不可以无节制、无选择的使用。


编程在继续,经验在积累,如有不同看法或者更好的理解欢迎来交流~~~~


 

你可能感兴趣的:(重构个人版机房收费系统——外观模式)