系统架构就是系统的骨骼,如果骨骼没有设计好,做出来的软件也会是畸形,怎样的架构才是合理的,怎样的架构才能造就一个健康的软件,那么健康的软件是什么样的?首先要满足用户需求,其次要有可修改性、灵活性、可维护性,也就是当用户需求改变时,尽量少更改已经封装好的东西,而且还要达到目的,这样的要求传统的面向过程的编码方式是很难实现的,而MVC三层架构就能实现这一切,V代表界面层,C代表业务逻辑层,M代表数据访问层。这个三层架构只是宏观意义上的三层,其实根据系统架构的需要可以分为更多层。除了这三层外还有一层是实体层,实体层对应着数据库中的表,每一张表映射为一个实体,下面介绍一下三层架构具体是什么样的:
1. 界面层只负责与用户交互,用户输入信息,在界面进行基本验证(是否为空、是否是数字等)将数据传到业务逻辑层,经过业务逻辑层处理后返回给界面层信息,界面将信息显示给用户。
2. 业务逻辑层负责接受界面的数据,进行业务处理(包括一些逻辑判断,计算等),需要数据库中的数据就调用数据访问层的方法,业务处理后给界面返回数据。
3. 数据访问层主要是一些操作数据库的类,查出的数据返回到业务逻辑层。
4. 实体层中每一个实体对应着数据库中的每一张表,实体类作为参数在三层之间传递。
下面以添加用户为例:
界面层(UI):当用户按下添加按钮后,首先检查输入框中的数据是否合法,然后将数据赋值给用户实体中的每个字段,调用B层的添加用户方法,将用户实体作为参数传递。
- Imports Bll
- Imports Entity
- Public Class FrmAddUser
- '实例化B层添加用户类
- Private BAddUser As New BllAddUser
- '实例化用户信息实体
- Private EUserInfo As New UserInfo
- Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
- '判断用户名文本框的输入是否为空
- If txtUserName.Text = "" Then
- MsgBox("用户名不能为空", vbOKOnly + vbExclamation, "警告")
- Exit Sub
- End If
- '判断密码文本框的输入是否为空
- If txtPwd.Text = "" Then
- MsgBox("密码不能为空", vbOKOnly + vbExclamation, "警告")
- Exit Sub
- End If
- '判断是否已经选择了用户级别
- If cmbLevel.Text = "" Then
- MsgBox("请选择用户级别", vbOKOnly + vbExclamation, "警告")
- Exit Sub
- End If
- '给实体的每个字段赋值
- EUserInfo.strUserName = txtUserName.Text.ToString
- EUserInfo.EuserPwd = txtPwd.Text
- EUserInfo.EuserLevel = cmbLevel.Text
- EUserInfo.EuserHead = FrmLogin.strUserName
- '执行添加用户
- Try
- If BAddUser.AddUser(EUserInfo) Then
- MsgBox("添加成功")
- Else
- MsgBox("未添加成功")
- End If
- Catch ex As Exception
- MsgBox(ex.Message)
- End Try
- '添加后清空文本框
- txtUserName.Text = ""
- txtPwd.Text = ""
- cmbLevel.Text = ""
- End Sub
业务逻辑层(Bll):首先判断界面传进来的用户实体是否已经存在(调用D层操作用户表中的检查用户方法),如果已经存在则抛出异常,如果不存在则向用户表中插入该用户实体(调用D层的操作用户表中的插入方法)。
Imports DAL
- Imports Entity
- Public Class BllAddUser
- '实例化用户信息实体
- Private EUserInfo As New UserInfo
- '实例化D层的操作用户信息
- Private DUserInfo As New DalUserInfo
- ''' <summary>
- ''' 添加用户
- ''' </summary>
- ''' <param name="EUserInfo"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function AddUser(ByVal EUserInfo As UserInfo) As Boolean
- Dim x As Boolean = False
- If DUserInfo.Check(EUserInfo.strUserName) Then
- Throw New Exception("该用户已经存在")
- Else
- x = DUserInfo.Insert(EUserInfo)
- Return x
- End If
- End Function
数据访问层(Dal):对数据库的操作,与数据库的连接字符串放在app.configer文件中,方便更换。其中的两个方法分别是检查数据库中是否存在某个用户,想数据库中用户表中插入一条记录。
- Imports System.Data.SqlClient
- Imports Entity
- ''' <summary>
- ''' 对用户表的操作
- ''' </summary>
- ''' <remarks></remarks>
- Public Class DalUserInfo
- Private connStr As String = Configuration.ConfigurationSettings.AppSettings("connStr")
- ''' <summary>
- ''' 检查用户是否存在
- ''' </summary>
- ''' <param name="strUserName"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function Check(ByVal strUserName As String) As Boolean
- Dim sql As String = "select * from user_Info where user_Name=@userName"
- Dim conn As New SqlConnection(connStr)
- Dim cmd As New SqlCommand(sql, conn)
- Dim sqlparam As New SqlParameter("@userName", SqlDbType.NChar)
- sqlparam.Value = strUserName
- cmd.Parameters.Add(sqlparam)
- Dim sdr As SqlDataReader = Nothing
- Try
- conn.Open()
- sdr = cmd.ExecuteReader()
- If sdr.Read Then
- Return True
- Else
- Return False
- End If
- Catch ex As Exception
- Return False
- Finally
- If Not IsNothing(conn) Then
- conn.Close()
- conn = Nothing
- End If
- If Not IsNothing(sdr) Then
- sdr.Close()
- sdr = Nothing
- End If
- If Not IsNothing(cmd) Then
- cmd.Dispose()
- cmd = Nothing
- End If
- End Try
- End Function
- ''' <summary>
- ''' 插入一条用户记录
- ''' </summary>
- ''' <param name="EUserInfo"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function Insert(ByVal EUserInfo As UserInfo) As Boolean
- Dim sql As String = "insert into user_Info values (@userName,@userPwd,@userLevel,@userHead)"
- Dim conn As New SqlConnection(connStr)
- Dim cmd As New SqlCommand(sql, conn)
- Dim sqlparam1 As New SqlParameter("@userName", SqlDbType.NChar)
- sqlparam1.Value = EUserInfo.strUserName
- cmd.Parameters.Add(sqlparam1)
- Dim sqlparam2 As New SqlParameter("@userPwd", SqlDbType.NChar)
- sqlparam2.Value = EUserInfo.EuserPwd
- cmd.Parameters.Add(sqlparam2)
- Dim sqlparam3 As New SqlParameter("@userLevel", SqlDbType.NChar)
- sqlparam3.Value = EUserInfo.EuserLevel
- cmd.Parameters.Add(sqlparam3)
- Dim sqlparam4 As New SqlParameter("@userHead", SqlDbType.NChar)
- sqlparam4.Value = EUserInfo.EuserHead
- cmd.Parameters.Add(sqlparam4)
- Try
- conn.Open()
- Return cmd.ExecuteNonQuery
- Catch ex As Exception
- Return False
- Finally
- If Not IsNothing(conn) Then
- conn.Close()
- conn = Nothing
- End If
- If Not IsNothing(cmd) Then
- cmd.Dispose()
- cmd = Nothing
- End If
- End Try
- End Function
- End Class
实体层:表中的字段都是私有的属性,他们的值的读写是通过属性过程来完成的。
- ''' <summary>
- ''' 用户表
- ''' </summary>
- ''' <remarks></remarks>
- Public Class UserInfo
- Public strUserName As String
- Private strUserPwd As String
- Private strUserLevel As String
- Private strUserHead As String
- Public Property EuserPwd As String
- Get
- Return strUserPwd
- End Get
- Set(ByVal value As String)
- strUserPwd = value
- End Set
- End Property
- Public Property EuserLevel As String
- Get
- Return strUserLevel
- End Get
- Set(ByVal value As String)
- strUserLevel = value
- End Set
- End Property
- Public Property EuserHead As String
- Get
- Return strUserHead
- End Get
- Set(ByVal value As String)
- strUserHead = value
- End Set
- End Property
- End Class