1.无论是对是错先学习前人的经验通过博客,一个功能至少看三人以上看其相同的地方并质疑其不同的地方
2.先敲出一条线(就是一个功能),能够自己敲最好,不能就借鉴前人,然后走一遍弄清其基本思想逻辑
3.及时总结并一个功能相继实现
什么是七层登录?
首先三层登录是U层获取界面信息,到B层根据业务需要进行逻辑判断做出相应的处理,B层进行整个操作所需的数据都要到D层进行数据的提取通过数据库,三层登录环环相扣,对于高内聚低耦合的原则是相悖的,于是就通过一些方式来对三层进行解耦,最后正好是七层(除SQLhelper外),所以便是七层登录,用到了两个设计模式facade(外观模式)
和factory(抽象工厂模式),解耦后的七层便是UI层、Facade层、BLL层、Factory层、I层(接口层)、DAL层、Entity(实体层)
Facade层:解耦了U层和B层,这样便减弱了两个类之间的关联,提高了代码的可维护性,这样无论U层和F层进行什么的改变只需去外观层进行相应的改动便可
Factory层:通过配置文件来选取相应的数据库,创建相应数据库接口,解耦了数据库的类型
IDAL层:D层通过创建的接口来输送B层所需要的数据,B层获取数据也要通过这个接口
通过图可知七层的引用关系为:
U层:Facade层和Entity层;Facade层:BLL层和Entity层;BLL层:Factory层和IDAL层和Entity层;
Factory层:IDAL层和Entity层;IDAL层:Entity层;DAL:实现IDAL并引用Entity层
为什么使用七层?
使用三层也可以实现系统的功能,然而这只是做到了面向对象的初步工作,我们做完一个系统更注重的是后期的不断完善与维护,如果前期不能很好的做到高内聚低耦合那么后期维护便是牵一发而动全身,工作量之大往往得不偿失,这便是软件危机的一种表现,使用七层便很好的做到了未雨绸缪,即使用七层不是为了做出系统而是为了做出能够简便地不断更新和维护的系统
七层是如何实现的?
下面以机房收费系统登录为例
UI层:用户给出相应的操作和数据,传递给Facade层,通过里面的方法去和BLL层进行交互
Public Class frmLogin
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
'进行输入框判断
If txtUserName.Text = "" Then
MessageBox.Show("请输入用户名!", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUserName.Focus()
ElseIf txtPassWord.Text = "" Then
MessageBox.Show("请输入密码!", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtPassWord.Focus()
End If
'实例化所需要的各层的类
Dim FacodeLogin As New Facade.LoginFAC
Dim UserInfo As New Entity.EntityUsersWork
'如果执行验证的时候有错误将给出相应的处理
Try
UserInfo.userID = txtUserName.Text.Trim()
UserInfo.pwd = txtPassWord.Text
Dim strResult As Boolean
'将U层的用户信息传给外观层
strResult = FacodeLogin.CheckUser(UserInfo) '判断用户是否存在
If strResult = False Then
MsgBox("用户名不存在!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUserName.Text = ""
txtPassWord.Text = ""
txtUserName.Select()
txtUserName.Focus()
End If
Dim table As DataTable
table = FacodeLogin.CheckPwd(UserInfo)
If Trim(txtPassWord.Text) = Trim(table.Rows(0).Item(1)) Then
'MsgBox("登录成功!")
frmMain.Show()
Me.Hide()
txtPassWord.Text = ""
txtUserName.Text = ""
End If
'出现验证从错误给出的相应处理
Catch ex As Exception
MsgBox("用户不存在或者密码不正确")
txtUserName.Text = ""
txtPassWord.Text = ""
txtUserName.Select()
txtUserName.Focus()
End Try
End Sub
End Class
Facade层:通过封装的方法去调用BLL层的对应具体业务逻辑,通过这个业务逻辑到D层里进行数据验证返回要验证的对象信息
Public Class LoginFAC
'检查用户名是否存在
Public Function CheckUser(ByVal UserInfo As Entity.EntityUsersWork) As Boolean
Dim IsUserExist As New BLL.UsersBLL
Dim result As Boolean
result = IsUserExist.CheckUser(UserInfo)
If result = True Then
Return True
Else
Return False
End If
End Function
'检查密码是否正确
Public Function CheckPwd(ByVal UserInfo As Entity.EntityUsersWork) As DataTable
Dim IsPwdExist As New BLL.UsersBLL
Dim table As DataTable
table = IsPwdExist.CheckPwd(UserInfo)
Return table
End Function
End Class
BLL层:通过
Imports IDAL
Public Class UsersBLL
'检验用户是否存存在的业务逻辑
Public Function CheckUser(ByVal UserInfo As Entity.EntityUsersWork) As Boolean
Dim Factory As New Factory.FactoryDB
Dim IUser As IDAL.IUser
'调用创建用户的工厂方法
IUser = Factory.CreateIUser() '调用工厂的create Iuser方法创建Iuser接口实例
Dim table As New DataTable
Dim result As Boolean
table = IUser.selectUser(UserInfo)
'进行用户是否存在的判断
If table.Rows.Count = 0 Then '此判断是什么意思??
result = False
Else
result = True
End If
Return result
End Function
'检验用户登录密码是否正确的业务逻辑
Public Function CheckPwd(ByVal UserInfo As Entity.EntityUsersWork) As DataTable
Dim Factory As New Factory.FactoryDB
Dim Iuser As IDAL.IUser
Dim table As DataTable
Iuser = Factory.CreateIUser
table = Iuser.selectUser(UserInfo)
Return table
End Function
End Class
Factory层:
Imports IDAL '引用接口层
'反射+配置文件+抽象工厂时间书库空访问
Public Class FactoryDB
Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称&命名空间DAL
Dim strDB As String = System.Configuration.ConfigurationManager.AppSettings("DB")
Public Function CreateIUser() As IUser
Dim classname As String = AssemblyName + "." + strDB + "UserDAL"
Dim IUser As IUser
'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口的结果
IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), IUser)
Return IUser
End Function
End Class
Iuser层:
Imports System.Data
Imports System.Data.SqlClient
Public Class SqlUserDAL : Implements IDAL.IUser
'实现接口中的方法
Private sqlHelper As New SQLHelp.sqlHelper
'判断用户是否存在
Public Function selectUser(UserInfo As Entity.EntityUsersWork) As DataTable Implements IDAL.IUser.selectUser
Dim sql As String '中间变量,用于存储从数据库中查找的信息
Dim table As DataTable
'声明并实例化参数数组
Dim sqlParams As SqlParameter() = {New SqlParameter("@userID", UserInfo.userID), New SqlParameter("@pwd", UserInfo.pwd)}
sql = "select * from userwork_Info where userID = @userID and pwd = @pwd"
'调取sqlhelper类中的Execselect()方法来执行查询,并获取返回值
table = sqlHelper.Execselect(sql, CommandType.Text, sqlParams)
Return table
End Function
DAL层
Imports System.Data
Imports System.Data.SqlClient
Public Class SqlUserDAL : Implements IDAL.IUser
'实现接口中的方法
Private sqlHelper As New SQLHelp.sqlHelper
'判断用户是否存在
Public Function selectUser(UserInfo As Entity.EntityUsersWork) As DataTable Implements IDAL.IUser.selectUser
Dim sql As String '中间变量,用于存储从数据库中查找的信息
Dim table As DataTable
'声明并实例化参数数组
Dim sqlParams As SqlParameter() = {New SqlParameter("@userID", UserInfo.userID), New SqlParameter("@pwd", UserInfo.pwd)}
sql = "select * from userwork_Info where userID = @userID and pwd = @pwd"
'调取sqlhelper类中的Execselect()方法来执行查询,并获取返回值
table = sqlHelper.Execselect(sql, CommandType.Text, sqlParams)
Return table
End Function
Entity层:
Public Class EntityUsersWork
'设置用户名属性
Private _userID As String
Public Property userID As String
Get
Return _userID
End Get
Set(value As String)
_userID = value
End Set
End Property
'设置密码属性
Private _pwd As String
Public Property pwd As String
Get
Return _pwd
End Get
Set(value As String)
_pwd = value
End Set
End Property
'设置等级属性
Private _level As String
Public Property level As String
Get
Return _level
End Get
Set(value As String)
_level = value
End Set
End Property
'设置用户姓名属性
Private _name As String
Public Property name As String
Get
Return _name
End Get
Set(value As String)
_name = value
End Set
End Property
'设置开户人属性
Private _head As String
Public Property head As String
Get
Return _head
End Get
Set(value As String)
_head = value
End Set
End Property
'设置日期属性
Private _date As Date
Public Property Logindate As Date
Get
Return _date
End Get
Set(value As Date)
_date = value
End Set
End Property
'设置时间属性
Private _time As TimeZone
Public Property Logintime As TimeZone
Get
Return _time
End Get
Set(value As TimeZone)
_time = value
End Set
End Property
'设置电脑属性
Private _computer As String
Public Property Usecomputer As String
Get
Return _computer
End Get
Set(value As String)
_computer = value
End Set
End Property
'设置修改密码属性
Private _oldpwd As String
Public Property oldpwd As String
Get
Return _oldpwd
End Get
Set(value As String)
_oldpwd = value
End Set
End Property
'设置状态属性
Private _status As String
Public Property status As String
Get
Return _status
End Get
Set(value As String)
_status = value
End Set
End Property
End Class
一般七层登录如果不用到配置文件和sqlhelper类就可以了,即把上面和配置文件+反射与sqlhelper相关的代码直接去掉就行,为了使类在解耦时更好的得到封装和减少代码的重复量便用到了配置文件和sqlhelper
配置文件: