程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 機房收費系統=三層+設計模式

機房收費系統=三層+設計模式

編輯:C#入門知識

 在簡單的三層登陸完成之後,我又在其中加入了設計模式,其中包括抽象工廠+反射和外觀模式.關於設計模式,在學習三層之前我們已經系統的學習過,可是在這次往機房收費系統中加設計模式時,還是感覺無從下手,出現了學沒有致用的尴尬情景.不過這也體現了我們提高班學習中項目驅動的優勢.

   接下來是我的一些現有思路,可能還不很准確,期待讀者朋友的指點.

   先說一下簡單的三層登陸思想吧:

   我們現階段接觸的三層就是最基本的三層--UI層,BLL層和DAL層.關於這三者之間的關系,在我前面博客中有所涉及,如果有興趣,你可以參看:三層架構入門.

   言歸正傳,理論知識我們知道了,在機房收費系統中,我們究竟是如何利用這三層來簡化靈活我們的代碼的呢?(由於.NET版本的登陸已經加入設計模式,所以簡單三層用C#語言來展示.)

   大家可以先看下主體代碼:

   UI層: 代碼如下:


[csharp]
<SPAN style="FONT-SIZE: 18px">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); 
        } 
</SPAN> 

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層: 代碼如下:

[csharp]
<SPAN style="FONT-SIZE: 18px">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("登錄失敗!"); 
            } 
        } 
</SPAN> 

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層: 代碼如下:

[csharp]
<SPAN style="FONT-SIZE: 18px">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;     
            } 
        } 
    } 

</SPAN> 

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接口,使用配置文件讀取數據庫字符串.通過反射技術,解除簡單工廠更換數據庫時的分支判斷帶來的耦合.

   代碼如下:

[vb]
<SPAN style="FONT-SIZE: 18px">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  
</SPAN> 

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層的耦合度極大降低.

[vb]
<SPAN style="FONT-SIZE: 18px">Imports Entity 
 
Public Interface IGetUserInfo 
    Function GetUserInfo(ByVal e_Users As Entity.E_UserInfoEntity) As DataTable 
End Interface 
</SPAN> 

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層的任何變動,都不會影響另一層.(這就是我們使用抽象工廠加反射的最大用處了.)


[vb]
<SPAN style="FONT-SIZE: 18px">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 
</SPAN> 

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層的分離.

[vb]
<SPAN style="FONT-SIZE: 18px">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 
</SPAN> 

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層就實現了分離,兩者中任何一層發生變化都不用修改另一層的代碼.

[vb]
<SPAN style="FONT-SIZE: 18px">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 
</SPAN> 

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


   上述是我現階段對三層和部分設計模式的理解,錯誤之處希望讀者朋友多多指教!

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved