• 机房收费系统=三层+设计模式


    在简单的三层登陆完成之后,我又在其中加入了设计模式,其中包括抽象工厂+反射和外观模式.关于设计模式,在学习三层之前我们已经系统的学习过,可是在这次往机房收费系统中加设计模式时,还是感觉无从下手,出现了学没有致用的尴尬情景.不过这也体现了我们提高班学习中项目驱动的优势.

    接下来是我的一些现有思路,可能还不很准确,期待读者朋友的指点.

    先说一下简单的三层登陆思想吧:

    我们现阶段接触的三层就是最基本的三层--UI,BLL层和DAL.关于这三者之间的关系,在我前面博客中有所涉及,如果有兴趣,你可以参看:三层架构入门

    言归正传,理论知识我们知道了,在机房收费系统中,我们究竟是如何利用这三层来简化灵活我们的代码的呢?(由于.NET版本的登陆已经加入设计模式,所以简单三层C#语言来展示.)

    大家可以先看下主体代码:

    UI: 代码如下:

     

    private void btnOK_Click(object sender, EventArgs e)
            {
                UserInfo user = new UserInfo();
                //向实体层传递参数
                string UserName = txtUserName.Text.Trim();
                string Password = txtPassword.Text.Trim();
                user.UserName=UserName ;
                user.Password = Password;
                //实例化BLL层,并调用BLL层方法
                LoginManager mgr = new LoginManager();
                UserInfo user2 = new UserInfo();
                user2 = mgr.UserLogin(user);
                MessageBox.Show("登录用户:" + user.UserName);
            }
    

    U,就是我们窗体类,是用户唯一可以看到的部分.其中不涉及连接数据库,也不会包括业务逻辑.它主要负责接收用户输入指令并传给实体类,再有实体类传给B,进行业务逻辑的判断.同时它也会根据B层产生的不同结果来及时反馈给用户.


    BLL: 代码如下:

    public  class LoginManager
        {
            public UserInfo UserLogin(UserInfo user)
            {
                //实例化DAL层,并调用DAL层方法
                UserDAO uDAO = new UserDAO();
                user = uDAO.SelectUser(user  );
                //逻辑判断代码
                if (user != null)
                {
                    ScoreDAO sDAO = new ScoreDAO();
                    sDAO.UpdateScore(user, 10);
                    return user;
                }
                else
                {
                    throw new Exception("登录失败!");
                }
            }
    

    这一层是业务逻辑层,顾名思义,它主要负责系统中的绝大部分逻辑判断,一旦U层或者D层出现业务逻辑判断,我们就要考虑,它是不是应该放在B.


    DAl: 代码如下:

    namespace Login.DAL
    {
         public  class UserDAO
        {
             /// <summary>
             /// 连接数据库,获取用户信息
             /// </summary>
             /// <param name="user">用户信息实体</param>
             /// <returns>用户信息</returns>
            public UserInfo  SelectUser(UserInfo user)
            {        
                using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))   //有待填写
                {
                    SqlCommand cmd = conn.CreateCommand();
                    cmd.CommandText = @"SELECT ID, UserName,Password,Email from Users where UserName=@UserName and Password=@Password";
                    cmd.CommandType = CommandType.Text;
                    
                    cmd.Parameters.Add(new SqlParameter ("@UserName",user.UserName  ));
                    cmd.Parameters.Add(new SqlParameter ("@Password",user.Password ));
                    conn.Open();
    
                    SqlDataReader reader = cmd.ExecuteReader();
                    user=null;
                    while (reader .Read ())//Read()方法:读取一个表的记录
                    {
                        if (user == null)
                        {
                            user = new UserInfo();
                        }
                        user.ID = reader.GetInt32(0);
                        user.UserName = reader.GetString(1);
                        user.Password = reader.GetString(2);
                        if (!reader.IsDBNull(3)) 
                        {
                            user.Email = reader.GetString(3);
                        }
                    }
                    return user;    
                }
            }
        }
    }
    

    从以上的代码就可以看出,D层主要是连接数据库,从数据库中读取信息,然后再以实体的形式传给B,B层传给U,最后表现在用户面前.

     

    上述是没有添加设计模式的简单三层登陆,下面就要谈一谈为什么要加设计模式,以及如何添加设计模式了.

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结.使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。也许这样说读者还是不大明白,下面的代码展示或许可以给您一些启示.

    首先说一下抽象工厂+反射,在机房登录中的应用(只展示主体代码,方便理解).

    Abstract Factory: 抽象工厂接口,它里面包含所有产品创建的抽象方法.工厂类被BLL层调用,并调用IDAL接口,使用配置文件读取数据库字符串.通过反射技术,解除简单工厂更换数据库时的分支判断带来的耦合.

    代码如下:

    Imports System.Configuration
    Imports System.Reflection
    Imports IDAL
    
    Public Class SqlFactory
        Private Shared ReadOnly AssemblyName As String = "DAL"
        '使用配置文件,读取数据库连接字符
        Private Shared DB As String = ConfigurationManager.AppSettings("strDB")
    
    #Region "获取用户信息"
        Public Shared Function CreatGetUserInfo() As IDAL.IGetUserInfo
            Dim UserInfo As IGetUserInfo
            Dim ClassName As String
            '反射技术,解除简单工厂更换数据库时的分支判断带来的耦合
            ClassName = AssemblyName + "." + DB + "D_GetUserInfo"
            UserInfo = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IDAL.IGetUserInfo)
            Return UserInfo
        End Function
    #End Region
    


    IDAL接口:  B层和D层调用,使得B层和D层的耦合度极大降低.

    Imports Entity
    
    Public Interface IGetUserInfo
        Function GetUserInfo(ByVal e_Users As Entity.E_UserInfoEntity) As DataTable
    End Interface
    

    BLL: 定义接口类,并使用工厂类SqlFactory方法反射实例化相应的DAl.这时候B层和D层已经完全不再耦合,B层或者D层的任何变动,都不会影响另一层.(这就是我们使用抽象工厂加反射的最大用处了.)

     

    Imports Entity
    Imports IDAL
    Imports DBFactory.SqlFactory
    Imports DAL
    
    Public Class B_UserInfo
        '创建工厂类,作用:创建接口对象
        Public SqlFactory As New DBFactory.SqlFactory
    #Region "验证用户密码"
        Public Function VerifyPassword(ByVal EUserInfo As E_UserInfoEntity) As Boolean
    
            '创建获得用户信息的接口
            Dim IGetPWD As IDAL.IGetUserInfo
            IGetPWD = DBFactory.SqlFactory.CreatGetUserInfo
            Dim dtUserInfo As DataTable
            dtUserInfo = IGetPWD.GetUserInfo(EUserInfo)
    
            If dtUserInfo.Rows.Count = 0 Then
                Throw New Exception("该用户还未注册!")
                Return False
            End If
    
            '判断密码是否正确
            If EUserInfo.Passwrod = Trim(dtUserInfo.Rows(0).Item(1)) Then
                Return True
            Else
                Return False
            End If
        End Function
    #End Region
    End Class
    


    抽象工厂和反射解耦和B层和D层.接下来的外观模式就要解耦U层和B层了.

    Facade类: 在简单的三层中,界面层的登陆需要根据B层返回的值再进行判断,这样B层和U层的耦合度是比较高的.而加入外观模式后,上面提到的对B层返回值进行判断就可以移到外观类中.这样就充分实现了B层和U层的分离.

    Imports Entity
    Imports BLL
    
    Public Class Login
        Private bUserInfo As New B_UserInfo
        Dim blnFlag As Boolean = False
        ''' <summary>
        ''' 对B层的返回值进行逻辑判断
        ''' </summary>
        ''' <param name="eUserInfo">用户信息实体</param>
        ''' <returns>用户信息正确返回True,错误返回False</returns>
        ''' <remarks></remarks>
        Public Function IsPassword(ByVal eUserInfo As E_UserInfoEntity) As Boolean
            Try
                blnFlag = bUserInfo.VerifyPassword(eUserInfo)
            Catch ex As Exception
                MsgBox(ex.Message, vbOKOnly, "提示信息")
            End Try
    
            If blnFlag = True Then
                Return True
            Else
                MsgBox("密码错误,请重新输入!")
                Return False
            End If
        End Function
    End Class
    


    UI:   外观层在对B层返回值进行判断之后,返回信息给UI层.这样U层和B层就实现了分离,两者中任何一层发生变化都不用修改另一层的代码.

    Imports Entity
    Imports BLL
    Imports Facade.Login
    
    
    Public Class frmLogin
        Public bUserInfo As New B_UserInfo
        Public faUserInfo As New Facade.Login
    
        Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
            Dim aUserInfo As New Entity.E_UserInfoEntity
            Dim blnFlag As Boolean = False
    
            aUserInfo.UserID = Trim(txtUserName.Text)
            aUserInfo.Passwrod = Trim(txtPassword.Text)
    
            '调用外观类的IsPassword方法进行逻辑判断
            Try
                blnFlag = faUserInfo.IsPassword(aUserInfo)
            Catch ex As Exception
                MsgBox(ex.Message, vbOKOnly, "提示信息")
            End Try
    
            If blnFlag = True Then
                frmMain.Show()
            End If
        End Sub
    End Class
    


    上述是我现阶段对三层和部分设计模式的理解,错误之处希望读者朋友多多指教!


  • 相关阅读:
    PHP的命令行脚本调用
    JAVA使用jar命令制作可执行GUI程序
    PHP的代理模式
    PHP中的__clone()
    PHP使用反射动态加载第三方类
    NAT小记
    JAVA睡眠理发师代码记录
    PHP通过反射获得类源码
    PHP中单引号双引号的区别
    [转载]PHP导出数据库数据字典脚本
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3212308.html
Copyright © 2020-2023  润新知