这次合作机房收费系统时,秉着学习的态度,尽量多用设计模式,所以经过思考,在上机那儿觉得可以用状态模式。
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。状态模式的目的就是为了消除庞大的条件分支语句,把各种状态转移逻辑分布到state的子类之间,减少相互间的依赖。
在机房收费系统中,上机时要判断卡是否存在,卡的余额是否足够,卡是否正在上机,然后卡上机写入一条上机记录。我们可以把这四种判断看着四种种状态,初始状态是判断卡是否存在,当卡存在时进入下一状态判断卡的余额是否足够,当余额足够时就判断是否正在上机,当没有在上机时就上机写入一条上机记录,如果不满足任一情况则抛出异常。
相对应的类图:
相应的代码:
OnLineStateBLL类:
Public Class OnLineStateBLL ''' <summary> ''' 上机 ''' </summary> ''' <param name="enCard"></param> Public Overridable Sub OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity, ByVal onLine As OnLineBLL) End Sub End Class
NotExitStateBLL类:
Public Class NotExitStateBLL Inherits BLL.OnLineStateBLL ''' <summary> ''' 上机 ''' </summary> ''' <param name="enCard"></param> Public Overrides Sub OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity, ByVal onLine As OnLineBLL) Dim dataAccess As Factory.FactoryReflex '定义一个工厂对象 dataAccess = Factory.FactoryReflex.GetInstance() '实例化工厂对象 Dim icard As ICard '定义一个接口 icard = dataAccess.CreateICard() '创建接口 Dim dtCard As New DataTable '定义一个datatable对象 dtCard = icard.SelectCardUse(enCard) '调用D层中查询卡的方法 '判断该卡是否存在 If dtCard.Rows.Count = 0 Then Throw New Exception("该卡不存在!") Else onLine.SetState(New LessLeastCashStateBLL) '转到下一状态 onLine.CardOnLine(enCard, enLineRecord) '调用OnLineBLL中的上机方法 End If End Sub End Class
LessLeastCashStateBLL类:
Public Class LessLeastCashStateBLL Inherits BLL.OnLineStateBLL ''' <summary> ''' 上机 ''' </summary> ''' <param name="enCard"></param> Public Overrides Sub OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity, ByVal onLine As OnLineBLL) Dim dataAccess As Factory.FactoryReflex '定义一个工厂对象 dataAccess = Factory.FactoryReflex.GetInstance() '实例化工厂对象 '查询系统基本数据 Dim ibasicData As IBasicData '定义一个接口 ibasicData = dataAccess.CreateIBasicData() '创建接口 Dim dtBasicData As New DataTable '定义一个datatable对象 dtBasicData = ibasicData.SelectBasicData() '查询系统的基本数据 '判断卡的余额是否大于最少金额 Dim icard As ICard '定义一个接口 icard = dataAccess.CreateICard() '创建接口 Dim dtCard As New DataTable '定义一个datatable对象 dtCard = icard.SelectCardUse(enCard) '查询卡的余额 '判断卡的余额是否足够 If CSng(dtCard.Rows(0).Item("卡内余额").ToString) < CSng(dtBasicData.Rows(0).Item("limitCash").ToString) Then Throw New Exception("金额不足" + dtBasicData.Rows(0).Item("limitCash").ToString + "元") Else onLine.SetState(New IsOnLineStateBLL) '转到下一状态 onLine.CardOnLine(enCard, enLineRecord) '调用OnLineBLL中的上机方法 End If End Sub End Class
IsOnLineStateBLL类:
Public Class IsOnLineStateBLL Inherits OnLineStateBLL ''' <summary> ''' 上机 ''' </summary> ''' <param name="enCard"></param> Public Overrides Sub OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity, ByVal onLine As OnLineBLL) Dim dataAccess As Factory.FactoryReflex '定义一个工厂对象 dataAccess = Factory.FactoryReflex.GetInstance() '实例化工厂对象 Dim ilineRecord As ILineRecord '定义一个接口 ilineRecord = dataAccess.CreateILine() '创建接口 Dim dtLineRecord As New DataTable dtLineRecord = ilineRecord.SelectIsOnLine(enLineRecord) '查询该卡是否正在上机 '判断该卡是否正在上机 If Not dtLineRecord.Rows.Count = 0 Then Throw New Exception("该卡正在上机!") Else onLine.SetState(New InsertLineRecordBLL) '转到下一状态 onLine.CardOnLine(enCard, enLineRecord) '调用OnLineBLL中的上机方法 End If End Sub End Class
InsertLineRecordBLL类:
Public Class InsertLineRecordBLL Inherits BLL.OnLineStateBLL ''' <summary> ''' 上机,插入一条上机记录 ''' </summary> ''' <param name="enCard"></param> Public Overrides Sub OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity, ByVal onLine As OnLineBLL) Dim dataAccess As Factory.FactoryReflex '定义一个工厂对象 dataAccess = Factory.FactoryReflex.GetInstance() '实例化工厂对象 Dim ilineRecord As ILineRecord '定义一个接口 ilineRecord = dataAccess.CreateILine() '创建接口 Dim bln As Boolean bln = ilineRecord.InsertOnLine(enLineRecord) '想上机记录表里插入一条上机记录 End Sub End Class
外观Facade中的代码:
''' <summary> ''' 上机,写入上机记录 ''' </summary> ''' <param name="enLineRecord">LineRecordEntity实体,(卡号,上机日期,上机时间,操作员,机器号)</param> Public Function OnLine(ByVal enCard As CardEntity, ByVal enLineRecord As LineRecordEntity) As DataTable Dim OnLineBll As New BLL.OnLineBLL Return OnLineBll.CardOnLine(enCard, enLineRecord) End Function