生活随笔
收集整理的这篇文章主要介绍了
机房收费系统之抽象工厂篇
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
机房收费系统vb.net个人版已完成,在此过程中分层的好处在系统的完成过程中得到了很好的体会。第一遍用的是纯三层做的,这几天又在此基础上又重构了登录的demo,加上抽象工厂和配置文件的使用。下面以登录功能为例,总结一下我的机房收费系统。
一、下面看一下我的包图:
可以看到,这张图是从最基本的三层UI→BLL→DAL加入设计模式(抽象工厂)演化而来的, 采用抽象工厂是考虑到日后更换数据库的方便。
二、准备工作
创建数据表(课参见实体类中的代码)
创建相应的类库和窗体。
我用的是vb.net的WidowsApplication来添加界面;使用类库作为其它层的包。
三、抽象各层的类
当我们确定了系统的整体架构,就要从宏观到微观的实现。
3.1 Entity(实体层)
数据库设计好了,我们要根据数据库中的表抽象实体类,系统中,实体类和表基本上是一一对象的。一个表映射一个实体类,表的字段即为实体类的属性。
实体层并不属于三层的任何一层,它是独立出来的一层,可以把它看做是自定义变量的组合,供其它三层使用。
[vb] view plaincopyprint?
Public Class UserInfoEntity #Region "定义UserInfo表中各个属性变量" Private _userName As String Private _name As String Private _password As String Private _userlevel As String Private _accountHolder As String Private _regDate As String Private _regTime As String #End Region #Region "定义数据表中各个字段名常量" Private Const DBFLELD_USERNAME = "userName" Private Const DBFLELD_NAME = "name" Private Const DBFLELD_PASSWORD = "password" Private Const DBFLELD_USERLEVEL = "userLevel" Private Const DBFLELD_ACCOUNTHOLDER = "accountHolder" Private Const DBFLELD_REGDATE = "regDate" Private Const DBFLELD_TIME = "regTime" #End Region #Region "定义数据表中各个字段参数变量" Public Const DBPARAM_USERNAME = "@userName" Public Const DBPARAM_NAME = "@name" Public Const DBPARAM_PASSWORD = "@password" Public Const DBPARAM_USERLEVEL = "@userLevel" Public Const DBPARAM_ACCOUNTHOLDER = "@accountHolder" Public Const DBPARAM_REGDATE = "@regDate" Public Const DBPARAM_TIME = "@regTime" #End Region Public Sub LoadFromDataRow(ByVal dr As DataRow) userName = dr(DBFLELD_USERNAME) name = dr(DBFLELD_NAME) password = dr(DBFLELD_PASSWORD) userlevel = dr(DBFLELD_USERLEVEL) accountHolder = dr(DBFLELD_ACCOUNTHOLDER) regDate = dr(DBFLELD_REGDATE) regTime = dr(DBFLELD_TIME) End Sub #Region "填充一条记录" Public Overloads Sub Fill(ByVal AuserName As String , ByVal Apassword As String , ByVal AuserLevel As String ) userName = AuserName password = Apassword userlevel = AuserLevel End Sub #End Region #Region "定义数据表中各个属性" Public Property userName() As String Get Return _userName End Get Set (ByVal value As String ) _userName = value End Set End Property Public Property name() As String Get Return _name End Get Set (ByVal value As String ) _name = value End Set End Property Public Property password() As String Get Return _password End Get Set (ByVal value As String ) _password = value End Set End Property Public Property userlevel() As String Get Return _userlevel End Get Set (ByVal value As String ) _userlevel = value End Set End Property Public Property accountHolder() As String Get Return _accountHolder End Get Set (ByVal value As String ) _accountHolder = value End Set End Property Public Property regDate() As String Get Return _regDate End Get Set (ByVal value As String ) _regDate = value End Set End Property Public Property regTime() As String Get Return _regTime End Get Set (ByVal value As String ) _regTime = value End Set End Property #End Region End Class
下面是配置文件的使用:在窗体层添加新项目→选中打开窗口的左边的General选项→添加配置文件,(中间部分是需要手动添加的)。
[vb] view plaincopyprint?
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings > <add key="connStr" value ="Data Source=.;Initial Catalog=Login;User ID=sa;Password=123456" /> <add key ="AssemblyName" value ="DAL" /> <add key ="db" value ="DB" /> </appSettings> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" /> </startup> </configuration>
3.2 DAL层(数据访问层)
接下来我们再看一下数据访问层(DAL),这一层的主要任务是直接操作数据库,完成对数据的增删改查等。这里我们仍然根据数据表来抽象 DAL 层的类,基本上也是一个表对应一个类,这样当我们增加新的表,直接增加新的 DAL 层类就可以,很好地符合了“开闭原则”。
另外,因为 DAL 层的类是直接对数据库进行操作的类,所以这个类里封转大都有四种方法:增删改查。但根据实际情况会有不同的参数,不同的返回值。
这里添加了接口层IDAL ,利用反射和抽象工厂,以防更换数据库。
3.2.1 接口层IDAL,添加Entity的引用。
[vb] view plaincopyprint?
Imports Entity Public Interface Iuser Function Check(ByVal entityUser As UserInfoEntity) As UserInfoEntity End Interface
3.2.2 DAL层实现IDAL接口
下面是DAL层下的DataAccess类
添加Configuration引用时需从.net子项目中查找,还要添加项目引用Entity和IDAL.
[vb] view plaincopyprint?
Imports System.Configuration Imports System.Reflection Imports System.Data.SqlClient Imports Entity Imports IDAL Public Class DataAccess #Region "连接数据库" Private ReadOnly connStr As String = ConfigurationManager.AppSettings("connStr" ) Public Overloads Function CreateConn() As SqlConnection Return New SqlConnection(connStr) End Function #End Region #Region "关闭相关对象" Public Sub Close(ByVal conn As SqlConnection) conn.Close() conn = Nothing End Sub Public Sub Close(ByVal cmd As SqlCommand) cmd.Dispose() cmd = Nothing End Sub #End Region Public Sub AddSqlParameter(ByVal cmd As SqlCommand, ByVal dbParam As String , ByVal dbType As SqlDbType, ByVal value As Object ) Dim sqlParam As SqlParameter = New SqlParameter(dbParam, dbType) sqlParam.Value = value cmd.Parameters.Add(sqlParam) End Sub End Class
DAL层下的DBuser类 :
同样添加项目引用Entity和IDAL.
[vb] view plaincopyprint?
Imports System.Data.SqlClient Imports Entity Imports IDAL Public Class DBuser Inherits DataAccess Implements Iuser Public Function Check(ByVal entityUser As Entity.UserInfoEntity) As UserInfoEntity Implements IDAL.Iuser.Check Dim sql As String = String .Format("select * from userInfo where [userName]={0} and [password]={1} and [userLevel]={2}" , UserInfoEntity.DBPARAM_USERNAME, UserInfoEntity.DBPARAM_PASSWORD, UserInfoEntity.DBPARAM_USERLEVEL) Dim conn As SqlConnection = CreateConn() Dim cmd As SqlCommand = New SqlCommand(sql, conn) Dim sda As SqlDataAdapter = New SqlDataAdapter(cmd) Dim ds As New DataSet AddSqlParameter(cmd, UserInfoEntity.DBPARAM_USERNAME, SqlDbType.VarChar, entityUser.userName) AddSqlParameter(cmd, UserInfoEntity.DBPARAM_PASSWORD, SqlDbType.VarChar, entityUser.password) AddSqlParameter(cmd, UserInfoEntity.DBPARAM_USERLEVEL, SqlDbType.VarChar, entityUser.userlevel) Try conn.Open() sda.Fill(ds, "userInfo" ) Dim dr As DataRow = ds.Tables("userInfo" ).Rows(0) entityUser.LoadFromDataRow(dr) Return entityUser Catch ex As Exception Return Nothing Finally Close(cmd) Close(conn) End Try End Function End Class
抽象工厂+反射+配置文件
[vb] view plaincopyprint?
Imports System.Configuration Imports System.Reflection Imports IDAL Public Class Factory #Region "配置加反射" Private Shared ReadOnly AssemblyName As String = ConfigurationManager.AppSettings("AssemblyName" ) Private Shared ReadOnly db As String = ConfigurationManager.AppSettings("db" ) Public Shared Function CreateUser() As Iuser Dim ClassName As String ClassName = AssemblyName + "." + db + "user" Return CType (Assembly .Load(AssemblyName).CreateInstance(ClassName), Iuser) End Function #End Region End Class
3.BLL层(封装业务层): 前提添加DAL,IDAL和Entity的引用
[vb] view plaincopyprint?
Imports IDAL Imports Entity Imports Factory Public Class BllLogin Public Function CheckRecord(ByVal entityUserInfo As UserInfoEntity) As Boolean Dim checkResult As Boolean Dim iuser As Iuser iuser = Factory.Factory.CreateUser() If Not IsNothing(iuser.Check(entityUserInfo)) Then checkResult = True Else checkResult = False End If Return checkResult End Function End Class
4.UI层(界面层)
界面层的类,就是我们窗体类,又多少个 窗体,UI层就有多少个类。
下面我们看一下登录窗体类。
[vb] view plaincopyprint?
Imports BLL Imports Entity Public Class frmLogin Private Sub btnLogin_Click(ByVal sender As System.Object , ByVal e As System.EventArgs) Handles btnLogin.Click If txtUserID.Text = "" Then MessageBox.Show("用户名不能为空!" ) txtUserID.Focus() Return End If If txtPassword.Text = "" Then MessageBox.Show("用户名不能为空!" ) txtPassword.Focus() Return End If Dim entityUserInfo As New UserInfoEntity entityUserInfo.Fill(Trim(txtUserID.Text), Trim(txtPassword.Text), Trim(cboUserLevel.Text)) Dim bllUserInfo As New BllLogin If bllUserInfo.CheckRecord(entityUserInfo) Then Me .Hide() frmMain.Show() Else MsgBox("登录失败" , vbOKOnly + vbInformation, "登录失败" ) txtUserID.Focus() Exit Sub End If End Sub Private Sub btnCancel_Click(ByVal sender As System.Object , ByVal e As System.EventArgs) Handles btnCancel.Click Me .Close() End Sub End Class
上面就是我在三层(UI→BLL→DAL)的基础上加上设计模式抽象工程实现系统登录的Demo,拿出来和大家一起分享,其中的不足之处,还希望大家多多指正。
总结
以上是生活随笔 为你收集整理的机房收费系统之抽象工厂篇 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔 网站内容还不错,欢迎将生活随笔 推荐给好友。