Login VB-OOP 實作前言
Login (登入/登錄) 動作,不管在任何應用系統 (AP, Application System)都能看到它的影子。像我的手機,一開機先問個 PIN 密碼...光一個手機,就能有好多密碼。- 進公司刷卡(Card);
- 提錢(Card);
- 上網(Accout/Password);
- 回家開門(Key);
- 開車(Key);
- 指紋(生物辨識);
你能發現每天從早到晚,其實都在不斷的 Login / Logout,出門上班,對「家」而言,你是 Logout,開車上班,對「車」而言,你是 Login,到達公司,對「車」而言,你是 Logout,進公司,必須刷卡才能進入,那是 Login,下班刷卡離開公司,那是 Logout。
指紋辨識,這幾年拜 NB 幫的忙,很多 NB 都把指紋辨識當成基本配備,省下了打 Keyboard 的時間,刷一下手指,超方便的。還記得,大學時在「國家太空中心」打工,國家太空中心可以使用「掌紋辨識」,在當時可以說是很先進方便,辨識率也不錯,就我在那裡打工時間裡,最少沒有出錯過。
以下是以程杰(大話設計模式作者) Blog 裡兩篇文章為基礎,以這兩篇文章實作出 Visual Basic 可執行版本。
非常推薦給學習過物件導向的人來看,Login 範例非常實用,只要是「AP」你一定會碰到 Login 問題,學習如何透過物件導向來處理此一問題。
我覺得另一重點是「思緒」,想想,如果是你,你會怎麼處理?是否會有一樣的思緒?而且我認為文章中提出的問題,都還算常見,不算是那種為了寫書或寫文章而特別設計的例子。
範例一:網頁登入 (CodeBehind) (對應文章 2007-7-1 對話)
WebForm_1 專案 - Login.aspx
Login.aspx 介面 HTML。<h2>網頁登錄 ( CodeBehind )</h2> <form id="form1" runat="server"> <div> <asp:Label ID="lbName" runat="server" Text="帳號:"></asp:Label> <asp:TextBox ID="tbName" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbPassword" runat="server" Text="密碼:"></asp:Label> <asp:TextBox ID="tbPassword" runat="server" TextMode="Password"></asp:TextBox> <br /> <br /> <asp:Button ID="btnLogin" runat="server" Text="登錄" /> </div> </form>
Login.aspx.vb CodeBehind 程式碼。
Public Class Login Inherits System.Web.UI.Page Protected Sub tbLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim userName As String = tbName.Text Dim passWord As String = tbPassword.Text If (login(userName, passWord)) Then Response.Redirect("LoginOK.aspx") Else Response.Redirect("LoginFail.aspx") End If End Sub Private Function login(userName As String, password As String) As Boolean ' 訪問資料庫,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
此範例為最最最基礎的 Login 程式碼,也是最最最一般的 Login 程式碼。注意,為了 Focus 在「Login」這件事情上面,我們的範例不會出現任何資料庫相關程式碼,要注意的地方,我都有打上註解。
另外準備兩個網頁, LoginOK.aspx及LoginFail.aspx,內容很簡易,一個打上「網頁登錄成功!」,一個打上「網頁登錄失敗!」,執行我們的第一個專案,這已經是一個能動的範例了。
範例二:手機登錄 ( Class UserAdmin ) (對應文章 2007-7-25 對話)
我個開一個新 WebForm 專案,假設它是手機登錄介面。
WebForm_2 專案 - Login.aspx
PhoneLogin.aspx 介面 HTML 同 WebForm_1 專案。
PhoneLogin.aspx.vb
Public Class Login Inherits System.Web.UI.Page Protected Sub tbLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim userName As String = tbName.Text Dim password As String = tbPassword.Text ' 使用 Class UserAdmin 提供的認證功能。 Dim ua As New UserAdmin If (ua.Login(userName, password)) Then Response.Redirect("LoginOK.aspx") Else Response.Redirect("LoginFail.aspx") End If End Sub End Class ''' <summary> ''' 用戶管理類別 ''' </summary> Public Class UserAdmin ''' <summary> ''' 登錄資料確認函式 ''' </summary> ''' <param name="userName">帳號</param> ''' <param name="password">密碼</param> ''' <returns>Boolean</returns> Public Function Login(userName As String, password As String) As Boolean ' 訪問資料庫,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
我們把原本的 Login 函式提升至一個 UserAdmin 類別裡,這樣就可以給大家共用。
範例三:WinForm 登錄 ( DataAccessLayer ) (對應文章 2007-7-29 對話)
DataAccessLayer (Windows --> 類別庫) 專案
將範例二的 Class UserAdmin 移至 DataAccessLayer 類別庫專案。
UserAdmin.vb
''' <summary> ''' 用戶管理類別 ''' </summary> Public Class UserAdmin ''' <summary> ''' 登錄資料確認函式 ''' </summary> ''' <param name="userName">帳號</param> ''' <param name="password">密碼</param> ''' <returns>Boolean</returns> Public Function Login(userName As String, password As String) As Boolean ' 訪問資料庫,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
移至類別庫後,我們必須在要使用專案裡「加入參考」--> 選擇「Projects」 --> 選擇「DataAccessLayer」,然後在程式即可使用。
WinForm_1 專案
我們先把 WinForm Login UI拉好,圖一:WinForm Login UI |
Public Class Form1 Private Sub bnLogin_Click(sender As System.Object, e As System.EventArgs) Handles bnLogin.Click Dim userName As String = tbName.Text Dim password As String = tbPassword.Text ' 使用 DataAccessLayer.UserAdmin 提供的認證功能。 Dim ua As New DataAccessLayer.UserAdmin If ua.Login(userName, password) Then lbMsg.Text = "WinForm 登錄成功!" Else lbMsg.Text = "WinForm 登錄失敗!" End If End Sub End Class
到這裡還算簡單。也讓我們學習到「類別庫」的使用,如果你還不會使用類別庫專案,請參考我的這一篇「元件類別(類別庫範本,Class Library) 」。
範例四:網頁登錄 (DataAccessLayer_DB)(對應文章 2007-8-3 對話)
此處會使用到「介面、繼承、多型」等特性。如果不懂,請參考「Visual Basic 裡 OOP 相關文章」。DataAccessLayer_DB 類別庫專案
我們重新整理整個 DataAccessLayer 為 DataAccessLayer_DB,使它可以實現切換資料庫時,不用去動到原始程式碼。IUserAdmin 介面,定義所有繼承類別必須要有一個「Login 函式」。
IUserAdmin.vb 介面
''' <summary> ''' 定義 Login 函式 ''' </summary> Public Interface IUserAdmin Function Login(userName As String, password As String) As Boolean End Interface
接下來我們繼承 IUserAdmin 介面,實作 Access, Oracle, Sql Server 三個類別。
UserAdminAccess.vb
Public Class UserAdminAccess Implements IUserAdmin ''' <summary> ''' 實作 Access 版本的 IUserAdmin ''' </summary> ''' <param name="userName">帳號</param> ''' <param name="password">密碼</param> ''' <returns>Boolean</returns> Public Function Login(userName As String, password As String) As Boolean Implements IUserAdmin.Login ' 訪問 Access,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
UserAdminOracle.vb
Public Class UserAdminOracle Implements IUserAdmin ''' <summary> ''' 實作 Oracle 版本的 IUserAdmin ''' </summary> ''' <param name="userName">帳號</param> ''' <param name="password">密碼</param> ''' <returns>Boolean</returns> Public Function Login(userName As String, password As String) As Boolean Implements IUserAdmin.Login ' 訪問 Oracle,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
UserAdminSqlServer.vb
Public Class UserAdminSqlServer Implements IUserAdmin ''' <summary> ''' 實作 SqlServer 版本的 IUserAdmin ''' </summary> ''' <param name="userName">帳號</param> ''' <param name="password">密碼</param> ''' <returns>Boolean</returns> Public Function Login(userName As String, password As String) As Boolean Implements IUserAdmin.Login ' 訪問 Sql Server ,進行帳號及密碼比對 ' --- 此處只是為了 Demo 方便,所以寫死 --- If userName = "kkbruce" And password = "12345" Then Return True Else Return False End If End Function End Class
這裡我們偷懶了,原因前面說過了,為了 Focus 在「Login」這件事情上面。雖然看起來都是一模一樣的程式碼,但在原應有的實作中,資料庫連線,SQL語法 … 都會有差異,尤其是在其他非MS系列資料庫,並不是都一樣,這裡我們再提醒一次。
Login.aspx.vb
Login UI HTML與範例一相同。我們直接程式碼。Public Class Login Inherits System.Web.UI.Page Private Sub btnLogin_Click(sender As Object, e As System.EventArgs) Handles btnLogin.Click Dim userName As String = tbName.Text Dim password As String = tbPassword.Text ' 討論一 ' 透過 DataAccessLayer_DB 可選擇對應的資料庫 Dim ua As New DataAccessLayer_DB.UserAdminAccess 'Dim ua As New DataAccessLayer_DB.UserAdminOracle 'Dim ua As New DataAccessLayer_DB.UserAdminSqlServer If ua.Login(userName, password) Then Response.Redirect("LoginOK.aspx") Else Response.Redirect("LoginFail.aspx") End If End Sub End Class
以上寫法只差一個問題,如果我們要更換資料庫的話,必須動到此主程式。
範例五:UserAdminFactory 工廠模式 (對應文章 2007-8-8 對話)
我們在範例四最後,透過「Dim ua As New DataAccessLayer_DB.UserAdminAccess」的方式來產生實體,一旦我們要更換資料庫,就必須更動主程式,這不是好辦法,比較好的辦法透過工廠模式來新增實體,這樣的話,要修改也不必更動到此主程式,所以我們在類別庫中再新增一個 UserAdminFactory.vb 的工廠類別。UserAdminFactory.vb 工廠類別
Public Class UserAdminFactory Private Shared ReadOnly db As String = "Access" ''' <summary> ''' 透過工廠來建立 IUserAdmin 實體,以去除程式碼中實體建立過程。 ''' </summary> Public Shared Function CreateUserAdmin() As IUserAdmin Dim iua As IUserAdmin = Nothing Select Case db Case "Access" iua = New UserAdminAccess Case "Oracle" iua = New UserAdminOracle Case "SqlServer" iua = New UserAdminSqlServer End Select Return iua End Function End Class
以原來主程式中產生實體改為使用工廠類別來產生。
' 討論二 ' --- 使用工廠來產生實體,當我們變更資料庫時,就不必修改此段程式碼 --- Dim ua As DataAccessLayer_DB.IUserAdmin = DataAccessLayer_DB.UserAdminFactory.CreateUserAdmin()
範例六:改進工廠,Reflection - Config (對應文章 2007-8-15 對話)
讓工廠依賴 *.config 檔。此處使用到 Reflection,如不清楚,請參考「Visual Basic Reflection 相關文章」。UserAdminFactory_Reflection.vb
Imports System.Configuration Imports System.Reflection Public Class UserAdminFactory_Reflection Private Shared ReadOnly AssemblyName As String = "DataAccessLayer_DB" Private Shared ReadOnly db As String = ConfigurationManager.AppSettings("DB") Public Shared Function CreateUserAdmin() As IUserAdmin ' 組合後的ClassName: DataAccessLayer_DB.UserAdminAccess Dim className As String = AssemblyName & ".UserAdmin" & db ' 透過 Reflection 產生對應的實體 Dim iua As IUserAdmin = CType(Assembly.Load(AssemblyName).CreateInstance(className),IUserAdmin) Return iua End Function End Class
然後,在修改 WebForm_3 專案 Web.config 加入 appSettings 相關設定。
修改Web.confg的AppSettings設定
<configuration> <appSettings> <add key="DB" value="Access"/> <!-- <add key="DB" value="Oracle"/> <add key="DB" value="SqlServer"/> --> </appSettings> <system.web> <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" /> </system.web> </configuration>
這樣之後,讓我們的工廠來依賴 Web.config 或 App.config,當我們需要更換資料庫時,所以程式碼都不必修改。最後主程式 Loging 使用 Reflection (反映) 版本的工廠。
Login.aspx.vb 使用 Reflection 工廠
Public Class Login Inherits System.Web.UI.Page Private Sub btnLogin_Click(sender As Object, e As System.EventArgs) Handles btnLogin.Click Dim userName As String = tbName.Text Dim password As String = tbPassword.Text ' 討論一 ' 透過 DataAccessLayer_DB 可選擇對應的資料庫 'Dim ua As New DataAccessLayer_DB.UserAdminAccess 'Dim ua As New DataAccessLayer_DB.UserAdminOracle 'Dim ua As New DataAccessLayer_DB.UserAdminSqlServer ' --- 以上也產生更換資料庫,必須更動程式碼的問題 --- ' --- 應該修改使用工廠來產生實體 --- ' 討論二 ' --- 使用工廠來產生實體,當我們變更資料庫時,就不必修改此段程式碼 --- 'Dim ua As DataAccessLayer_DB.IUserAdmin = DataAccessLayer_DB.UserAdminFactory.CreateUserAdmin() ' 討論三 ' --- 使用 Reflection 來產生實體 --- ' --- 注意:Web.config 裡的 appSettings 段落 --- ' --- 透過修改 Web.config 設定檔,就能達到不修改程式而更換資料庫 --- Dim ua As DataAccessLayer_DB.IUserAdmin = DataAccessLayer_DB.UserAdminFactory_Reflection.CreateUserAdmin() If ua.Login(userName, password) Then Response.Redirect("LoginOK.aspx") Else Response.Redirect("LoginFail.aspx") End If End Sub End Class
範例七:打卡與指紋登錄 (DataAccessLayer_FingerMark)(對應文章 2007-9-23 對話)
本篇一剛頭我們就討論過,Login 的方法千奇百怪,例如「家」,除了 Key 之外,你還可能有申請安裝保全服務,那除了 Key 之外,連「家」都必須刷卡,你才能安心的 Login / Logout。所以不要覺得這裡的需求很奇怪。Users.vb
使用者登錄相關屬性。''' <summary> ''' 使用者登錄相關屬性類別 ''' </summary> Public Class Users Public Property UserID() As Integer Public Property UserName() As String Public Property Password() As String Public Property CardID() As String Public Property FingerMark() As String End Class
修改 IUserAdmin 介面,使用 Users 類別。
IUserAdmin 介面 - 使用 Users類別
''' <summary> ''' 定義 Loging 函式,使用 Users 類別 ''' </summary> Public Interface IUserAdmin Function Login(user As Users) As Boolean End Interface
接下來,我們新增三個類別來繼承實作此 IUserAdmin 介面,UserAdminAccess.vb、UserAdminOracle.vb、UserAdminSqlServer.vb。
UserAdminAccess.vb
Public Class UserAdminAccess Implements IUserAdmin ''' <summary> ''' 實作 Access 版本的 IUserAdmin ''' </summary> ''' <param name="user">使用者相關屬性</param> ''' <returns>Boolean</returns> ''' <remarks></remarks> Public Function Login(user As Users) As Boolean Implements IUserAdmin.Login ' 訪問Access,進行帳號及密碼比對 ' --- 我們假設"指紋"與"CardID"是一個字串比對 --- ' --- 只要任一條件通過認證即可 --- If NameAndPassword(user) OrElse FingerMark(user) OrElse CardID(user) Then Return True Else Return False End If End Function ' 以下三個依"重構原則"而重構而來的回應條件函式 ' 正常情況下,return 的內容,必須與各別資料庫做確認,不合適提升至 Users.vb 裡 Private Shared Function NameAndPassword(ByVal user As Users) As Boolean Return user.UserName = "kkbruce" AndAlso user.Password = "12345" End Function Private Shared Function FingerMark(ByVal user As Users) As Boolean Return user.FingerMark = "67890" End Function Private Shared Function CardID(ByVal user As Users) As Boolean Return user.CardID = "8888" End Function End Class
UserAdminAccess.vb
Public Class UserAdminOracle Implements IUserAdmin ''' <summary> ''' 實作 Oracle 版本的 IUserAdmin ''' </summary> ''' <param name="user">使用者相關屬性</param> ''' <returns>Boolean</returns> ''' <remarks></remarks> Public Function Login(user As Users) As Boolean Implements IUserAdmin.Login ' 訪問Oracle,進行帳號及密碼比對 ' --- 我們假設"指紋"與"CardID"是一個字串比對 --- ' --- 只要任一條件通過認證即可 --- If NameAndPassword(user) OrElse FingerMark(user) OrElse CardID(user) Then Return True Else Return False End If End Function ' 以下三個依"重構原則"而重構而來的回應條件函式 ' 正常情況下,return 的內容,必須與各別資料庫做確認,不合適提升至 Users.vb 裡 Private Shared Function NameAndPassword(ByVal user As Users) As Boolean Return user.UserName = "kkbruce" AndAlso user.Password = "12345" End Function Private Shared Function FingerMark(ByVal user As Users) As Boolean Return user.FingerMark = "67890" End Function Private Shared Function CardID(ByVal user As Users) As Boolean Return user.CardID = "8888" End Function End Class
UserAdminAccess.vb
Public Class UserAdminSqlServer Implements IUserAdmin ''' <summary> ''' 實作 Sql Server 版本的 IUserAdmin ''' </summary> ''' <param name="user">使用者相關屬性</param> ''' <returns>Boolean</returns> ''' <remarks></remarks> Public Function Login(user As Users) As Boolean Implements IUserAdmin.Login ' 訪問 Sql Server,進行帳號及密碼比對 ' --- 我們假設"指紋"與"CardID"是一個字串比對 --- ' --- 只要任一條件通過認證即可 --- If NameAndPassword(user) OrElse FingerMark(user) OrElse CardID(user) Then Return True Else Return False End If End Function ' 以下三個依"重構原則"而重構而來的回應條件函式 ' 正常情況下,return 的內容,必須與各別資料庫做確認,不合適提升至 Users.vb 裡 Private Shared Function NameAndPassword(ByVal user As Users) As Boolean Return user.UserName = "kkbruce" AndAlso user.Password = "12345" End Function Private Shared Function FingerMark(ByVal user As Users) As Boolean Return user.FingerMark = "67890" End Function Private Shared Function CardID(ByVal user As Users) As Boolean Return user.CardID = "8888" End Function End Class
再提醒一次,這三個類別只是我們方便 Demo,所以程式都長的一樣,但真實實作上會所有不同。
為了不複雜範例,工廠我們使用前面 UserAdminFactory.vb 這個版本的廠工類別。
fingerLogin.aspx 指紋登錄
這裡我們新增一個 Webform_4 專案,假設它是使用指紋登錄,而在程式上,我們又假設指紋是一個字串。fingerLogin.aspx UI HTML
<h2>指紋登錄 (DataAccessLayer_fingerMark)</h2> <form id="form1" runat="server"> <div> <asp:Label ID="lbFinger" runat="server" Text="指紋:"></asp:Label> <asp:TextBox ID="tbFinger" runat="server"></asp:TextBox> <br /> (假設 FingerMark 是 String = "67890") <br /> <asp:Button ID="btnLogin" runat="server" Text="登錄" /> </div> </form>
先加入類別庫的參考,接下來我們來使用 Users 類別及fingerMark來登入。
Public Class fingerLogin Inherits System.Web.UI.Page Protected Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim user As New DataAccessLayer_fingerMark.Users user.FingerMark = tbFinger.Text Dim ua As DataAccessLayer_fingerMark.IUserAdmin = DataAccessLayer_fingerMark.UserAdminFactory.CreateUserAdmin() If ua.Login(user) then Response.Redirect("LoginOK.aspx") Else Response.Redirect("LoginFail.aspx") End If End Sub End Class
程式碼沒有特別的地方,就是使用 Users 類別,然後由工廠產生實體,最後進行登錄驗證。
接下去為第二篇補充篇內容。
DataAccessLayer_Final and WebForm_5
將驗證分離出來成為一個介面,各自實作驗證方法。最後這個範例,我們特別一些,我們將會把處理後的 SQL 語法顯示出來,來代表是登錄。ICredentials 介面
''' <summary> ''' 定義驗證函式 ( 產生對應的 SQL 語法) ''' </summary> Public Interface ICredentials Function CredentialUser() As String End Interface
以下是"帳號/密碼"、"刷卡"、"指紋"三者驗證方法作。
CredentialsNamePassword.vb 類別(帳號/密碼驗實作)
''' <summary> ''' Name - Password 憑證 ( SQL 語法:Name - Password 條件) ''' </summary> Public Class CredentialsNamePassword Implements ICredentials Public Property UserName() As String Public Property Password() As String Public Function CredentialUser() As String Implements ICredentials.CredentialUser ' 注意:以下寫法會有 Sql Injection 的問題。 Return " UserName='" & Me.UserName & "' and Password = '" & Me.Password & "'" End Function End Class
CredentialsCard.vb 類別 (刷卡驗證方法實作)
''' <summary> ''' CardID 憑證 ( SQL 語法:CardID 條件) ''' </summary> Public Class CredentialsCard Implements ICredentials Public Property CardID() As String Public Function CredentialUser() As String Implements ICredentials.CredentialUser Return " CardID='" & Me.CardID & "'" End Function End Class
CredentialsFingerMark 類別(指紋驗證方法實作)
''' <summary> ''' FingerMark 憑證 ( SQL 語法:FingerMark 條件) ''' </summary> Public Class CredentialsFingerMark Implements ICredentials Public Property FingerMark() As String Public Function CredentialUser() As String Implements ICredentials.CredentialUser Return " FingerMark='" & Me.FingerMark & "'" End Function End Class
這裡主要是要回傳 SQL 語法 Where 的條件式。
IUserAdmin.vb 介面 -- 修改使用 ICredentials 介面
''' <summary> ''' 定義 Loging 函式 (使用 ICredentials 介面) ''' </summary> Public Interface IUserAdmin Function Login(credentials As ICredentials) As String End Interface
最後是三個繼承 IUserAdmin 介面的實作類別。
UserAdminSqlServer.vb 類別
Public Class UserAdminSqlServer Implements IUserAdmin ''' <summary> ''' 實作 Sql Server 版本的 IUserAdmin ''' </summary> ''' <param name="credentials">SQL Server憑證</param> ''' <returns>String (SQL 語法)</returns> Public Function Login(credentials As ICredentials) As String Implements IUserAdmin.Login Dim sqltxt As String = "select userid from users where" sqltxt &= credentials.CredentialUser() ' 使用 sqltxt 進行資料庫比對 ' 以下假設是比對後的結果 (顯示 SQL 語法) Return sqltxt End Function End Class
另外兩個程式碼一模一樣,我就不在重覆了。(UserAdminAccess.vb、UserAdminOracle.vb)
WebForm_5 專案
先參考 DataAccessLayer_Final 類別庫專案。這裡只有一個 Login.aspx,你輸入資料後會顯示組合後的 SQL 語法。Login.aspx UI HTML
<h2>網頁登入 (DataAccessLayer_Final)</h2> <form id="form1" runat="server"> <div> <asp:Label ID="lbName" runat="server" Text="帳號:"></asp:Label> <asp:TextBox ID="tbName" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbPassword" runat="server" Text="密碼:"></asp:Label> <asp:TextBox ID="tbPassword" runat="server" TextMode="Password"></asp:TextBox> <br /> <br /> <asp:Button ID="btnLogin" runat="server" Text="登錄" /> <br /> <br /> <asp:Label ID="lbSql" runat="server"></asp:Label> </div> </form>
Login.aspx.vb 後端程式碼
Public Class Login Inherits System.Web.UI.Page Protected Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click ' 使用帳號-密碼方式來驗證 Dim credentials As New DataAccessLayer_Final.CredentialsNamePassword credentials.UserName = tbName.Text credentials.Password = tbPassword.Text ' 使用 Sql Server Dim ua As DataAccessLayer_Final.IUserAdmin = DataAccessLayer_Final.UserAdminFactory.CreateUserAdmin() If String.IsNullOrEmpty(tbName.Text) AndAlso String.IsNullOrEmpty(tbPassword.Text) Then If ua.Login(credentials) <> "" Then lbSql.Text = String.Format("SQL 語法:{0}", ua.Login(credentials)) End If Else lbSql.Text = "" End If End Sub End Class
這樣我們就完成最後一個範例。
以上為尊重原作者,我對於程式碼盡量原汁原味。不過Allen大大有些指教,保留以下對話,讓大家更進一步了解,好還可以更好。
回覆刪除* Dim ua As DataAccessLayer_fingerMark.IUserAdmin =DataAccessLayer_fingerMark.UserAdminFactory.CreateUserAdmin()
* 這裡可以改一下
* 你在這class裡,去寫了讀取config 值並用reflection生出物件
* 但其實經由一個字串,生出物件,應該是由一支utility 的class來做,而不是寫在UserAdminFactory裡面
* UserAdminFactory裡頂多只需要叫用這支utility就可以了
才不會有好多class都寫了一些reflection的程式碼
...
*Private Shared ReadOnly AssemblyName As String = "DataAccessLayer_DB"
* 這也是不對的
* 因為,在實務上,你也許一開始寫了access, sql ,oracle,並編譯成DataAccessLayer_DB.dll裡
* 但一年後,若又需要加mysql呢?
* 其實並不是去改這支dll哦
* 而是加寫一支dll
* 因此,你不宜將dll filename寫死而是在config 裡面寫成
*
* 日後若需要mysql,就寫成
*
讀者來信:
回覆刪除你好,最近我要做1個project.其中有關於VB和MS SQL的部份..
所以有在關注你的blog,裡面內容很豐富,給了我很大的幫助..謝謝!^^
我看了你寫的Login/登入/登錄之物件導向實作
裡面有好幾個範例,但省略了一些細節.
我研究了好久都研究不到..所以想向你請教一下...
我想做的login界面是連接我的sql database取用戶 帳號 和密碼的...
我想做到先查用戶名稱是否存在,不存在就有msgbox提示用戶名稱不正確.
如果用戶名稱存在了,再配對密碼是否正確,不正確再出msgbox提示密碼不對這樣子..
希望大大能詳細指教一下..謝謝...
回答:
本篇的重點在於OOP觀念上,而非程式碼實作上。
至於你所提到的Login問題,方法-邏輯其實你已經自行提供了,只差程式碼實作部份。
我建議參考另一位MVP 91哥的文章:http://www.dotblogs.com.tw/hatelove/category/5036.aspx
前幾篇都是以Login為範例。
如果你實作出來的程式碼有任何問題,歡迎再討論。