博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
机房收费系统之重新设计
阅读量:5079 次
发布时间:2019-06-12

本文共 13226 字,大约阅读时间需要 44 分钟。

      这段时间,一直在实践一个小型的mis系统。像这种小型的mis系统,对数据库的操作无非就是增删改查。在做的时候,就在考虑一个问题,实现这样的系统,是否有一个比较通用的模式。

      我们都知道面向对象,要想实现低耦合,接口起了很大的作用。而接口最主要的作用则是实现一种多态。而要实现多态,并不是给方法加个接口,然后实现这么简单。他还需要有一个类,见,程序因为有了AnimalBark类,才体现出了他的优势。很好的将多态的优点表示出来。技术因需要而变得重要,一个程序实现它的灵活性确实很重要,但也要由实际情况而定。如果一个需求,他确实变动的可能比较大,或是实践方式比较多,这时候,用多态确实很好。可是如果,它的变动不是很大的话,用多态除了复杂,并不能体现它的什么好处。而且,一个事物都有相当于都没有。只有需要的地方有,才能体现它的优点与好处。

    说一下我这次的设计,这次的考虑,尽可能的减少提供给外部的接口,给有相似功能的行为提供一个对外接口。尽可能的让一个接口承担更多的功能,提高其内聚性。

     看一下实例:

      我们都知道mvc的三层结果。界面层,控制层,数据层。在这里我重点设计的是控制层与数据层的接口。

      先看一下包图:  机房收费之重新设计 - 小鱼儿 - 姚艳梅的博客

在这里,控制层通过工厂与数据层进行打交道。而工厂提供给控制层的只有Insert,Delete,Modify,Find四个接口。工厂通过传进来实体类的类型,来确定你到底要实例化的是哪个数据层的接口类。具体实现见方法SqlObjectCreate。(这里还有个小技巧,实体类和数据层类后缀都是一样的。如EnRegist,SqlRegist;EnUser,SqlUser)

 
1 ''''''''''''''''''''''''''''''''''''''
2  '工厂类,数据层与bll层的接口。b层的所有方法
3 '都必须通过此工厂的四个方法去调用数据层具体的接口
4 '12:24  5/8  5
'''''''''''''''''''''''''''''''''''''
6  Imports Entity
7 Imports System.Configuration
8 Imports IDAL
9 Imports System.Reflection
10
11 Public Class dalFactory
12     Private db As String   '连接数据库的类型
13     Private className As String '要实例化的具体的类名称
14     Private AssemblyName As String   '程序集名称
15     ''' 
16     ''' 所有程序调用数据库添加操作的入口
17     ''' 
18     ''' 实体类参数
19     ''' 
是否添加成功
20     ''' 
5/8 12:19
21     Public Function Insert(ByVal enObject As Object) As Boolean
22         Return objCreate(enObject).Add(enObject)
23     End Function
24     ''' 
25     ''' 所有程序调用数据库删除操作的入口
26     ''' 
27     ''' 实体类参数
28     ''' 
是否删除成功
29     ''' 
5/8 12:20
3
0     Public Function Delete(ByVal enObject As Object) As Boolean
31         Return objCreate(enObject).delete(enObject)
32     End Function
33     ''' 
34     ''' 所有程序调用数据库修改操作的接口
35     ''' 
36     ''' 实体类参数
37     ''' 
是否修改成功
38     ''' 
5/8 12:21
39     Public Function Modify(ByVal enObject As Object) As Boolean
40         Return objCreate(enObject).modify(enObject)
41     End Function
42     ''' 
43     ''' 所有程序调用数据库查询操作的接口
44     ''' 
45     ''' 调用的是哪种类型的查询
46     ''' user 查询类型,1按级别查询该级别对应的记录2按用户名查询
47     ''' basicdata 1 取得基本数据,表中就一条基本数据
48     ''' charge
49     ''' 1按卡号查询
50     ''' 2按时间段查询
51     ''' 3按操作员查询未结账的信息
52     ''' 4按操作员查询未结账的充值总额
53     ''' line
54     ''' 1按卡号查询上机信息
55     ''' 2查找所有正在上机的学生信息
56     ''' 3操作员未结账的上机消费总额
57     ''' operate 查询所有正在上机的操作员信息
58     ''' order 按时间段查询
59     ''' regist 1按卡号进行查询
60     ''' 2按操作员进行查询
61     ''' return 1按时间段查询
62     ''' 2 操作员未结账的退卡信息查询
63     ''' 3操作员未结账退卡总金额查询
64     ''' 
65     ''' 起始参数
66     ''' 终止参数
67     ''' 
查询到的结果
68     ''' 
5/8 12:22
69     Public Function Find(ByVal intNum As Integer, ByVal enObjectStart As Object, ByVal enObjectEnd As Object) As DataTable
70         Return objCreate(enObjectStart).find(intNum, enObjectStart, enObjectEnd)
71     End Function
72     ''' 
73     ''' 所有要实例化类的入口。根据传进去参数所属类型的不同,实例化不同的类对象
74     ''' 
75     ''' 实体类
76     ''' 
具体实例化的数据层类的对象
77     ''' 
5/8 11:36
78     Private Function objCreate(ByRef enObject As Object) As Object
79         Dim strType As String '用来接收传进来对象的类型,以判断到底要调用哪个类的数据层
80         strType = enObject.GetType.ToString
81         Return sqlObjectCreate(strType)
82     End Function
83     ''' 
84     ''' 实例化具体数据层类,输入类型,输出该类型对应的应实例化的类
85     ''' 这里有个技巧,数据层与实体类实例化对象除了前缀不同的,其他的地都是相同的。
86     ''' 
87     ''' 
实例化后的类
88     ''' 
5/8 11:34
89     Private Function sqlObjectCreate(ByVal strType As String) As Object
90         db = System.Configuration.ConfigurationManager.AppSettings("DB") '取得连接字符串
91         AssemblyName = "DAL"
92         Dim strTemp As String '用来判定具体应该返回那种类型的实例
93         strTemp = Mid(strType, 10, strType.Length - 9) '获取实体与数据层公共的部分
94         '具体实例化类的名字。取得所传过来变量的后几位,即把前缀给去掉。如entity.Regist变成Regist
95         className = AssemblyName + "." + db + Mid(strType, 10, strType.Length - 9)
96         Dim objReturn As New Object '用来取得具体的返回类型实例
97         '由实体类与数据层的公共部分,判定到底返回的是哪种类型的对象
98         Select Case strTemp
99             Case "User"
100                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IUser)
101                 'objReturn = Assembly.Load(AssemblyName).CreateInstance(className)
102             Case "BasicData"
103                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IBasicData)104             Case "Charge"
105                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), ICharge)
106             Case "Line"
107                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), ILine)
108             Case "OperateWork"
109                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IOperateWork)
110             Case "Order"
111                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IOrder)
112             Case "Regist"
113                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IRegist)
114             Case "Return"
115                 objReturn = CType(Assembly.Load(AssemblyName).CreateInstance(className), IReturn)
116         End Select
117         Return objReturn
118         'Return New classname
119     End Function
120 End Class
 
 

可能你会有疑问,查询到方式多种多样,一个接口能解决这个问题吗,可以看一下Find方法的注释,由于我们先能够确定出具体是哪个数据层,然后进行调用的时候,只需要知道那个数据层Find方法具体是怎么实现的就可以了。这里通过前面一个int型参数来确定具体要调用的是那种查询方式。

通过一个具体的过程来看一下这个程序是如何走的。

看一个查询。界面

 
1 ''''''''''''''''''''''''''''''''''
2 '按卡号查找充值信息
3 '23:24  5/9
4 ''''''''''''''''''''''''''''''
5 Imports BLL
6 Public Class frmChargeCheck
7     Private Sub btnCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheck.Click
8         Dim bllCharge As New bllCharge '实例化充值控制层
9         '将查询到的结果与控件进行绑定
10         dgvContent.DataSource = bllCharge.findByCardNo(txtCardNo.Text)
11     End Sub
12  End Class
 
 

控制层

 
1 ''''''''''''''''''''''''''
2 '充值控制层
3 '5/8 21:13
4 ''''''''''''''''''''''
5 Imports Entity
6 Public Class bllCharge
7     Private dalFactory As dalFactory.dalFactory '定义工厂类变量
8    ''' 
9     ''' 按卡号查找充值信息
10    ''' 
11     ''' 卡号
12     ''' 
该卡号对应的充值信息
13     ''' 
14     Public Function findByCardNo(ByVal strCardNo As String) As DataTable
15         dalFactory = New dalFactory.dalFactory '实例化工厂类
16         Dim enCharge As New enCharge '用来传递卡号
17         enCharge.CardNo = strCardNo '给其装载卡号
18         '返回查询的结果
19         Return dalFactory.Find(1, enCharge, enCharge)
20     End Function
21 End Class
 
 

看一下充值接口层(这里显示他实际所拥有的功能)

 
1 '''''''''''''''''''''''
2 '充值数据层接口
3 '5/8 17:01
4 '''''''''''''''''''''''
5 Imports Entity
6 Public Interface ICharge
7     ''' 
8     ''' 充值,向充值记录中添加记录
9     ''' 
10     ''' 充值记录,除结账状态,其他属性都以赋值
11     ''' 
是否充值成功
12     ''' 
13     Function Add(ByVal enCharge As enCharge) As Boolean
14     ''' 
15     ''' 查询总入口
16     ''' 
17     ''' 
18     ''' 查询类型变量
19     ''' 1按卡号查询
20     ''' 2按时间段查询
21     ''' 3按操作员查询未结账的信息
22     ''' 4按操作员查询未结账的充值总额
23     ''' 
24     ''' 开始记录
25     ''' 结束记录
26     ''' 
查询到的充值信息
27     ''' 
28     Function Find(ByVal intNum As Integer, ByVal enChargeStart As enCharge, ByVal enChargeEnd As enCharge) As DataTable
29 End Interface
 
 

具体的数据层,通过它你可以看到实际上它有多种查询方式,可是对外界开发的接口却只有一个Find

 
1 '''''''''''''''''''''''
2 '充值数据层
3 '13:55 5/8
4 '''''''''''''''''''''''
5 Imports IDAL
6 Imports Entity
7 Imports System.Data.SqlClient
8 Public Class SqlCharge
9     Implements ICharge
10     ''' 
11     ''' 将sqlhelper类实例化
12     ''' 
13     ''' 
14     Private sqlHelper As SQLHelper
15     ''' 
16     ''' 要执行的sql字符串
17     ''' 
18     ''' 
19     Private strSql As String
20     ''' 
21     ''' 实例化的command对象
22     ''' 
23     ''' 
24     Private cmd As SqlCommand
25     ''' 
26     ''' 用来接收执行结果是否成功
27     ''' 
28     ''' 
29     Private blResult As Boolean
30     ''' 
31     ''' 充值,向充值记录中添加记录
32     ''' 
33     ''' 充值记录,除结账状态,其他属性都以赋值
34     ''' 
是否充值成功
35     ''' 
36     Public Function Add(ByVal enCharge As Entity.enCharge) As Boolean Implements IDAL.ICharge.Add
37         sqlHelper = New SQLHelper()
38         strSql = "procCharge"
39         cmd = New SqlCommand(strSql, sqlHelper.conGet())
40         '指定cmd类型,用存储过程
41         cmd.CommandType = CommandType.StoredProcedure
42         '给command对象添加参数
43         sqlHelper.SqlParameterAdd(cmd, "@CardNo", SqlDbType.VarChar, enCharge.CardNo)
44         sqlHelper.SqlParameterAdd(cmd, "@ChargeTime", SqlDbType.DateTime, enCharge.ChargeTime)
45         sqlHelper.SqlParameterAdd(cmd, "@OperatorName", SqlDbType.VarChar, enCharge.OperatorName) 46         sqlHelper.SqlParameterAdd(cmd, "@Charge", SqlDbType.Money, enCharge.Charge)
47         sqlHelper.SqlParameterAdd(cmd, "@LastBalance", SqlDbType.Money, enCharge.LastBalance)
48         sqlHelper.SqlParameterAdd(cmd, "@CurrentBalance", SqlDbType.Money, enCharge.CurrentBalance) 49         '执行,并将结果返回给blresult
50         blResult = sqlHelper.ExecuteNonQuery(strSql, cmd)
51         Return blResult
52     End Function
53     ''' 
54     ''' 查询总入口
55     ''' 
56     ''' 
57     ''' 查询类型变量
58     ''' 1按卡号查询
59     ''' 2按时间段查询
60     ''' 3按操作员查询未结账的信息
61     ''' 4按操作员查询未结账的充值总额
62     ''' 
63     ''' 开始记录
64     ''' 结束记录
65     ''' 
查询到的充值信息
66     ''' 
67     Public Function Find(ByVal intNum As Integer, ByVal enChargeStart As Entity.enCharge, ByVal enChargeEnd As Entity.enCharge) As System.Data.DataTable Implements IDAL.ICharge.Find
68         Dim dt As New DataTable '用来接收返回的结果
69         Try
70             Select Case intNum
71                 '按卡号查找充值信息
72                 Case 1
73                     dt = findByCardNo(enChargeStart)
74                     '按时间段查找充值信息
75                 Case 2
76                     dt = findByTime(enChargeStart, enChargeEnd)
77                 Case 3
78                     '按操作员查找未结账的充值信息
79                     dt = findByOperator(enChargeStart)
80                 Case 4
81                     '按操作员查找未结账的充值总额
82                     dt = chargeSumFindByOper(enChargeStart)
83             End Select
84         Catch ex As Exception
85             dt = Nothing
86         End Try
87         Return dt
88     End Function
89     ''' 
90     ''' 按卡号查找充值信息
91     ''' 
92     ''' 充值记录,只包含卡号属性就可以
93     ''' 
该卡号对应的充值信息
94     ''' 
95     Private Function findByCardNo(ByVal enCharge As enCharge) As DataTable
96         sqlHelper = New SQLHelper()
97         Dim dt As New DataTable '用来接收查询的结果
98         '给sql语句赋值
99         strSql = "select * from Charge where CardNo=@CardNo"
100         cmd = New SqlCommand(strSql, sqlHelper.conGet())
101         sqlHelper.SqlParameterAdd(cmd, "@CardNo", SqlDbType.VarChar, enCharge.CardNo)
102         dt = sqlHelper.ExecuteQuery(strSql, cmd)
103         Return dt
104     End Function
105     ''' 
106     ''' 按时间段查找充值信息
107     ''' 
108     ''' 充值的开始时间,只要时间就行
109     ''' 充值的结束时间,只要时间就可以
110     ''' 
该时间段内的充值信息
111     ''' 
112     Private Function findByTime(ByVal enChargeStart As enCharge, ByVal enChargeEnd As enCharge) As DataTable
113         sqlHelper = New SQLHelper()
114         Dim dt As New DataTable '用来接收查询到 结果
115         strSql = "select * from Charge where ChargeTime between @start and @end"
116         cmd = New SqlCommand(strSql, sqlHelper.conGet())
117         '添加参数
118         sqlHelper.SqlParameterAdd(cmd, "@start", SqlDbType.Date, enChargeStart.ChargeTime)
119         sqlHelper.SqlParameterAdd(cmd, "@end", SqlDbType.Date, enChargeEnd.ChargeTime)
120         '接收查询到的结果
121         dt = sqlHelper.ExecuteQuery(strSql, cmd)
122         Return dt
123     End Function
124     ''' 
125     ''' 该操作员未结账的充值信息
126     ''' 
127     ''' 充值记录,只包含操作员就行
128     ''' 
该操作员未结账的充值信息
129     ''' 
130     Private Function findByOperator(ByVal enCharge As enCharge) As DataTable
131         sqlHelper = New SQLHelper()
132         Dim dt As New DataTable '用来接收查询的结果
133         '给sql语句赋值
134         strSql = "select * from Charge where OperatorName=@Oper and OrderState='未结账'"
135         cmd = New SqlCommand(strSql, sqlHelper.conGet())
136         sqlHelper.SqlParameterAdd(cmd, "@Oper", SqlDbType.VarChar, enCharge.OperatorName)
137         dt = sqlHelper.ExecuteQuery(strSql, cmd)
138         Return dt
139     End Function
140     ''' 
141     ''' 该操作员未结账的充值总额
142     ''' 
143     ''' 充值记录,只包含操作员就行
144     ''' 
该操作员未结账的充值总额
145     ''' 
146     Private Function chargeSumFindByOper(ByVal enCharge As enCharge) As DataTable
147         sqlHelper = New SQLHelper()
148         Dim dt As New DataTable '用来接收查询的结果
149         '给sql语句赋值
150         strSql = "select sum(Charge) from Charge where OperatorName=@Oper and OrderState='未结账'"
151         cmd = New SqlCommand(strSql, sqlHelper.conGet())
152         sqlHelper.SqlParameterAdd(cmd, "@Oper", SqlDbType.VarChar, enCharge.OperatorName)
153         dt = sqlHelper.ExecuteQuery(strSql, cmd)
154         Return dt
155     End Function
156 End Class
 

转载于:https://www.cnblogs.com/yanmei-yaomy/archive/2011/05/23/3025125.html

你可能感兴趣的文章
ionic2+ 基础
查看>>
互联网模式下我们更加应该“专注”
查看>>
myeclipse集成jdk、tomcat8、maven、svn
查看>>
查询消除重复行
查看>>
Win 10 文件浏览器无法打开
查看>>
HDU 1212 Big Number(C++ 大数取模)(java 大数类运用)
查看>>
-bash: xx: command not found 在有yum源情况下处理
查看>>
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
hiho1079 线段树区间改动离散化
查看>>
【BZOJ 5222】[Lydsy2017省队十连测]怪题
查看>>
第二次作业
查看>>
【input】 失去焦点时 显示默认值 focus blur ★★★★★
查看>>
Java跟Javac,package与import
查看>>
day-12 python实现简单线性回归和多元线性回归算法
查看>>
Json格式的字符串转换为正常显示的日期格式
查看>>
[转]使用 Razor 进行递归操作
查看>>
[转]Android xxx is not translated in yyy, zzz 的解决方法
查看>>
docker入门
查看>>
Android系统--输入系统(十一)Reader线程_简单处理
查看>>