您的位置:首页 > 运维架构 > 网站架构

三层架构实战篇 下

2014-06-16 15:59 274 查看
         上篇博客几乎是手把手的教大家怎样做一个三层结构的demo,但是实现和运行出这个例子不是我们的目的,我们的目标是学习,所以这一次我们要用VB.NET将demo实现,并且还要对demo进行一些完善。

         作为一个系统登录的demo,其核心业务就是用户输入信息,然后系统验证此用户是否有权限进入系统,并返回验证结果,仅此而已,那么有什么需求是会变化呢?仔细一想,UI不会有什么大的变化,BLL层主要是处理业务逻辑的,对登录来讲也没什么变化,那么只有DAL层了,DAL层是用来访问数据库,而数据库不仅仅有SQL Server一种,如果换成Oracle或者DB2,还能实现登录系统吗?显然是不能的,如何解决?

         这时候,是该考虑使用设计模式了,那么用什么模式呢?根据需求,当然是工厂方法模式了,但是单纯的工厂方法模式并不能解决多个数据库和多个表之间的切换问题,再想有什么办法,那就是抽象工厂模式了,它可以解决这种涉及多个产品系列的问题,但是如果要增加功能,那么改动的地方太多……算了直接使用绝招吧——反射+抽象工厂+配置文件。

         首先我给出加了设计模式的包图

        


         然后我们就打开VS2012,新建一个VB.NET的Windows窗体应用程序,然后按照包图的结构,构建三层结构,并为每层添加需要的类和接口,完成后如下图:

        


         然后我们就可以,按照一定的顺序去编写各个类的代码了,我偏好从下往上写,也就是从数据访问层开始,当然要考虑继承关系,总得先有父类吧,还有就是高层类比如抽象类等就得先写,come on……

         插入代码

         实体层DataEntity的UserInfo类

        

Public Class UserInfo
Private _userID As Integer
Private _userName As String
Private _password As String
'各个属性值的定义
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 Password() As String
Get
Return _password
End Get
Set(value As String)
_password = value
End Set
End Property
End Class


         接口层IDAL的IUserInfo类

        

Imports DataEntity

Public Interface IUserInfo
Function UserLogin(ByVal user As DataEntity.UserInfo) As DataEntity.UserInfo

End Interface


         抽象工厂Factory的DataAccess类

Imports System.Reflection
Imports System.Configuration
Imports IDAL

Public Class DataAccess
Dim DBstr As String = System.Configuration.ConfigurationSettings.AppSettings("DB")

Public Function CreateUser() As IDAL.IUserInfo
Return CType(Assembly.Load("LoginDAL").CreateInstance("LoginDAL" & "." & DBstr), IUserInfo)
End Function
End Class<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">	</span>


         表示层LoginUI的配置文件App.config

        

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="Connstr" value ="server =192.168.24.191;database=login;user id=sa;password=123456;" />
<add key ="DB" value ="Sqlserver"/>
</appSettings>
</configuration>


         数据访问层LoginDAL的Sqlserver类

        

Imports System.Data.SqlClient
Imports DataEntity
Imports IDAL

Public Class Sqlserver : Implements IUserInfo
Dim strConn As String = System.Configuration.ConfigurationSettings.AppSettings("Connstr")
Dim conn As SqlConnection = New SqlConnection(strConn)

Public Function UserLogin(user As UserInfo) As UserInfo Implements IUserInfo.UserLogin
Dim Sqlserver As String = "select * from Users where UserName =@username"
Dim cmd As SqlCommand = New SqlCommand(Sqlserver, conn)
cmd.Parameters.Add(New SqlParameter("@username", user.UserName))
Dim reader As SqlDataReader

Dim user1 As New UserInfo
Try
conn.Open()
reader = cmd.ExecuteReader
While reader.Read()
user1.UserName = reader.Item("UserName")
user1.Password = reader.Item("Password")
End While

Return user1
Catch ex As Exception
MsgBox(ex.Message.ToString())
Return user
Finally
conn.Close()
End Try
End Function
End Class


         业务逻辑层LoginBLL的LoginManager类

Imports Factory
Imports IDAL
Imports DataEntity

Public Class LoginManager
Public Function IdentifyUser(ByVal user As DataEntity.UserInfo) As UserInfo
Dim Iuser As IDAL.IUserInfo
Dim dataAccess As New DataAccess
Dim duser As UserInfo

Iuser = dataAccess.CreateUser()
duser = Iuser.UserLogin(user)
Return duser

End Function
End Class


         表示层LoginUI的客户端代码

        

Imports DataEntity
Imports LoginBLL

Public Class Form1

Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Try
Dim user1 As New UserInfo
Dim user2 As New UserInfo
Dim loginmanager As New LoginManager

user1.UserName = txtUserName.Text.Trim()
user1.Password = txtPassword.Text

user2 = loginmanager.IdentifyUser(user1)
If user2.UserName = user1.UserName And user2.Password = user1.Password Then
MsgBox("登陆成功!请稍后……")
Exit Sub
Else
MsgBox("该用户信息不存在,请重新输入!")
Exit Sub
End If

Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Close()
End Sub
End Class


         总结:通过对这么一个小的例子加设计模式和反射机制以及配置文件等等,主要是为了学习和实践,一开始我也觉得根本没有必要,甚至认为是过度设计,但是当自己参考设计模式的书准备将这个例子进行改进和扩展的时候,才发现自己根本不知道如何下手,不过经过查阅博客和贵人相助,终究是调试运行起来了,同时也对三层的理解加深了一些。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息