七层登陆的华丽转身
来源:互联网 发布:淘宝男裤子店铺排名 编辑:程序博客网 时间:2024/04/30 03:08
概述
三层结构主要体现出对程序分而治之的思想:数据访问层只负责提供原始数据,并不需要了解业务逻辑;业务逻辑层调用数据访问层提供的方法自定义一些业务逻辑,对数据进行加工,本身不需要了解数据访问层的实现;表示层直接调用业务逻辑提供的方法把数据呈现给用户。而为了更好的追求面向对象的高内聚和低耦合,加入适当的设计模式是必不可少的。通过对设计模式中抽象工厂和外观模式的应用,将三层架构的登陆进行升级和扩充,也就是变成了现在的七层。
具体的架构和关系如图所示
如图,该七层登陆使用了表现层UI、外观层Facade、业务逻辑层BLL、数据接口层IDAL、数据访问层DAL、工厂层Factory、实体层Entity和数据库操作组件类SQLHelper共同组成。
实体层Entity
实体类,在我一开始接触三层的时候以为它就是三层的一层,通过不断的加深理解,认识到实体层的存在是为了在各层之间起到一个数据传输的作用。我们知道,实体层是定义属性的,而这些属性就是数据库中我们所用到的字段。但是,直到读了一个文档,才知道,实体类什么也不是!它在三层架构中是可有可无的。它其实就是面向对象编程中最基本的东西:类。它在三层架构中的位置,和Int,string等变量的地位是一样的,没有其他的目的,仅仅是为了用于数据存储而已,只不过它存储的是复杂的数据。所以,如果你的项目非常简单,不用实体类而直接传递多个参数也是可以的。
但是,为什么我要还是要使用实体类呢?我们可以通过具体的应用来看:
在各层传递参数时,可以这样:
AddUser(userId,userName,userPassword,…,)
也可以这样:
AddUser(userInfo)
这两种方法那个好呢。一目了然,肯定是第二种要好很多。所以当我们要传递的参数非常多的时候,使用实体类会大大减少我们的工作量。
也可以这样:
AddUser(userInfo)
这两种方法那个好呢。一目了然,肯定是第二种要好很多。所以当我们要传递的参数非常多的时候,使用实体类会大大减少我们的工作量。
外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一个子系统更加容易使用。
在曾与层之间建立外观层Facade,这样可以为复杂的子系统提供一个简单的接口,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
抽象工厂
抽象工厂模式:提供一个创建一系列相关或相互依赖的接口,而无需指定他们具体的类。用反射+配置文件实现数据访问程序。这样就能更加的符合开放-封闭的原则,将抽象工厂的优点完全发挥出来。
下面让我们看一看配置文件的代码:
<?xml version="1.0" encoding="utf-8" ?><configuration> <connectionStrings> <add name ="ConnString" connectionString ="Data Source=DESKTOP-F8291CO;Initial Catalog=Login;User ID=sa;Password=123456"/> </connectionStrings> <appSettings> <clear/> <add key="DBString" value="Sql server"/> </appSettings></configuration>
代码实现
通过上述所述,三层架构结合设计模式,最终生成的解决方案如图所示:
SQLHelper
SqlHelper是一个基于.NET Framework的数据库操作组件。组件中包含数据库操作方法。SqlHelper用于简化你重复的去写那些数据库连接(SqlConnection),SqlCommand,SqlDataReader等等。SqlHelper 封装过后通常是只需要给方法传入一些参数如数据库连接字符串,SQL参数等,就可以访问数据库了,很方便。具体内容详见这里。
Imports System.Data.SqlClientImports System.ConfigurationPublic Class SqlHelper Dim DBConnectStr As New DALUtil Dim DBConnection As New SqlConnection(DBConnectStr.ConnectString) Dim cmd As New SqlCommand '设置连接 '定义cmd命令 Public Function ExecAddDelUpdate(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As Integer '将传入的值,分别为cmd的属性赋值 cmd.Parameters.AddRange(sqlParams) '将参数传入 cmd.CommandType = cmdType '设置一个值,解释cmdText cmd.Connection = DBConnection '设置连接,全局变量 cmd.CommandText = cmdText '设置查询的语句 Try DBConnection.Open() '打开连接 Return cmd.ExecuteNonQuery() '执行增删改操作 cmd.Parameters.Clear() '清除参数 Catch ex As Exception Return 0 '如果出错,返回0 Finally Call CloseConn(DBConnection) Call CloseCmd(cmd) End Try End Function Public Function ExecAddDelUpdate(ByVal cmdText As String, ByVal cmdType As CommandType) As Integer '为要执行的命令cmd赋值 cmd.CommandText = cmdText '先是查询的sql语句 cmd.CommandType = cmdType '设置Sql语句如何解释 cmd.Connection = DBConnection '设置连接 '执行操作 Try DBConnection.Open() Return cmd.ExecuteNonQuery() Catch ex As Exception Return 0 Finally Call CloseConn(DBConnection) Call CloseCmd(cmd) End Try End Function Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As DataTable '执行查询操作,有参数 Dim adapter As SqlDataAdapter Dim dt As New DataTable Dim ds As New DataSet cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = DBConnection cmd.Parameters.AddRange(sqlParams) adapter = New SqlDataAdapter(cmd) Try adapter.Fill(ds) dt = ds.Tables(0) cmd.Parameters.Clear() Catch ex As Exception Throw New Exception("查询失败!") Finally Call CloseCmd(cmd) End Try Return dt End Function Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType) As DataTable '执行查询操作,无参数 Dim adapter As SqlDataAdapter Dim ds As New DataSet cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = DBConnection adapter = New SqlDataAdapter(cmd) Try adapter.Fill(ds) Return ds.Tables(0) Catch ex As Exception Return Nothing Finally Call CloseCmd(cmd) End Try End Function Public Sub CloseConn(ByVal conn As SqlConnection) If (conn.State <> ConnectionState.Closed) Then '如果没有关闭 conn.Close() '关闭连接 conn = Nothing '不指向原对象 End If End Sub Public Sub CloseCmd(ByVal cmd As SqlCommand) If Not IsNothing(cmd) Then '如果cmd命令存在 cmd.Dispose() '销毁 cmd = Nothing End If End SubEnd Class
实体层
Public Class LoginEntity Private _userName As String Private _passWord As String 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 PropertyEnd Class
U层
Imports EntityImports FacadeImports Entity.AllUsePublic Class frmLogin Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim fac As New Facade.LoginFacade '定义一个外观对象 Dim fac1 As New Facade.LoginFacade Dim dt As DataTable Dim UserInfo As New Entity.LoginEntity '定义一个实体类对象 Try If txtUserName.Text.Trim() = "" Or txtPassWord.Text.Trim() = "" Then MsgBox("用户ID或密码不可为空", , "警告") ElseIf IsNumeric(Trim(txtUserName.Text)) = False Then MsgBox("用户名请输入数字!", , "警告") txtUserName.Text = "" Else UserInfo.UserName = Val(txtUserName.Text.Trim()) '将U层数据传给实体层 UserInfo.PassWord = txtPassWord.Text.Trim() dt = fac.CheckUser(UserInfo) If Trim(UserInfo.PassWord) <> dt.Rows(0).Item(1).trim() Then MsgBox("密码错误") txtPassWord.Text = "" txtPassWord.Focus() Else AllUserID = txtUserName.Text.Trim() Me.Hide() frmMDImain.Show() End If End If Catch ex As Exception MsgBox("用户不存在或者密码不正确!") txtPassWord.Text = "" txtUserName.Text = "" txtUserName.Focus() End Try End Sub
Facade层
Imports EntityImports BLLImports System.ReflectionPublic Class LoginFacade Public Function CheckUser(ByVal UserInfo As Entity.LoginEntity) As DataTable Dim IsUes As New BLL.LoginBLL() Dim dt As DataTable dt = IsUes.IsUserExists(UserInfo) Return dt End Function
B层
Imports IDALPublic Class LoginBLL Public Function IsUserExists(ByVal UserInfo As Entity.LoginEntity) As DataTable Dim fac As New Factory.LoginFactory() Dim Iuser As IDAL.ILoginDAL '调用“创建用户”的工厂方法 Dim dt As DataTable Iuser = fac.CreateUserInfo dt = Iuser.SelectUser(UserInfo) If dt.Rows.Count = 0 Then MsgBox("没有该用户信息!") End If Return dt End FunctionEnd Class
工厂层
Imports System.Configuration '添加对配置文件的引用Imports System.Reflection '添加对反射的引用Imports IDALPublic Class LoginFactory Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBString") Public Function CreateUserInfo() As IDAL.ILoginDAL 'Ctype是一个内联函数,将前面的部分转化未后半部分 'LoginDAL为程序集名称 'Login.DAL为命名空间名称 'IUserInfoDal为要实例化的“类名” 'CreateUserInfo 创建实例 Return CType(Assembly.Load("DAL").CreateInstance("DAL.LoginSQL"), IDAL.ILoginDAL) End FunctionEnd Class
接口层
Imports System.ReflectionPublic Interface ILoginDAL Function SelectUser(ByVal UserInfo As Entity.LoginEntity) As DataTableEnd Interface
D层
Imports System.Data.SqlClientImports EntityImports IDALImports SQLHelperPublic Class LoginSQL : Implements IDAL.ILoginDAL Public Function SelectUser(UserInfo As LoginEntity) As DataTable Implements ILoginDAL.SelectUser Dim shelper As New SQLHelper.sqlHelper Dim cmdType As CommandType = New CommandType() Dim paras As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserName), New SqlParameter("@PassWord", UserInfo.PassWord)} Dim cmdText As String cmdText = "Select * from Users where UserName=@UserName And PassWord=@PassWord" Dim dt As New DataTable dt = shelper.ExecSelect(cmdText, CommandType.Text, paras) Return dt End FunctionEnd Class
Public Class DALUtil 'Public Shared Function connstring() As String ' connstring = "Server=.;Databse=Login;User ID=sa;Password=123456" '连接SQL的字符串 'End Function Private ReadOnly db As String = System.Configuration.ConfigurationManager.AppSettings("DBString") '数据库 Private ReadOnly ConnectStr As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnString").ToString 'sql数据库连接字符串 Public connectString As String = ConnectStrEnd Class
总结:通过对七层登陆的实现,对整个程序进行单步调试,使得对整个程序的数据流的传递方式和过程更加清晰,对于各个层之间的相互引用也理解的更加深刻,为个人机房重构打下了很好的基础,同时也让我深深的意识到解耦和的重要性,对于三层架构和设计模式的理解和运用也要通过不断地积累和应用来变得更加熟练。通过这几天的学习,让我对面向对象的兴趣越来越大,继续努力吧!
6 0
- 七层登陆的华丽转身
- 剩饭--华丽的转身
- 腾讯的华丽转身
- 程序媛华丽丽的转身
- 程序员的华丽转身(1)
- 程序员的华丽转身(2)
- 再见,我的HTML!华丽转身!
- iOS 程序猿华丽的转身
- 年终总结--凤凰涅槃,一次华丽的转身
- 未来30年,程序员的华丽转身
- 英特尔的华丽转身x86 CPU的跨越式进步
- 还原当年创业:屌丝逆袭后的华丽转身 (zz)
- path2.0 UI path 2.0的华丽转身
- 20岁高中辍学者“华丽转身”背后的坚持
- 互联网百人研发团队的华丽转身
- 看看滴滴大牛是如何从码农到AI的华丽转身
- 华丽的前台登陆页面
- 七层登陆
- 【转】centos的软件安装方法rpm和yum
- UIScrollView的delegate方法妙用之让UICollectionView滑动到某个你想要的位置
- 判断浏览器是否支持某个CSS属性
- NYoj 40 公约数和公倍数
- 一步步搭建web服务器(3)
- 七层登陆的华丽转身
- Android FloatMath.ceil过时的解决办法
- 如何用adb查看android终端分辨率?
- Linux下安装Nginx
- activity被回收,fragment恢复处理
- 创建第一个ionic APP项目
- Notepad++中zen-Coding使用
- Android ToolBar 基本使用
- Objective-C多个UIButton同时点击问题