设计模式之——状态模式

本文深入讲解状态模式的应用原理,通过实例展示如何利用状态模式解决复杂的业务逻辑判断问题,实现代码的扩展性和维护性。

一、基础篇

含义:状态模式(State):当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是党控制一个对象状态转换的条件过于复杂的情况,把状态的判断转移到表示不同状态的一系列类当中,从而实现复杂的判断逻辑简化的目的。同样的,当判断需要增加的时候,也可以将状态类增加,减少了多分支情况下的修改量,也符合了软件开发中的‘开放—封闭原则’

结构图

优点与用处:将特定的状态相关的行为局部化,并且将不同状态的行为分割开来。简单来说,就是为了消除庞大的条件分支语句。因为大的分支判断会使得系统变得复杂而难以修改和扩展。这就类似我们中国四大发明中的印刷术一样。复杂的分支判断就像是雕版印刷术,而状态模式就像北宋时期发明的活字印刷术,从而使得整个业务系统变得容易扩展和维护

二、应用篇

在机房收费系统中,如果用面向过程的思想来说,有很多复杂的业务逻辑判断分支结构,例如学生上机。对于学生上机,首先我们需要判断用户是否存在,其次判断用户是否已经上机,再次,判断用户余额是否大于系统最低上机金额要求,最后就是将学生上机信息添加到正在上机表中。

抽象类


''' <summary>
''' 抽象状态类,让其他各个状态类去继承
''' </summary>
''' <remarks>提供一个上机方法,让其他子类进行继承</remarks>
Public Class State

    Public Overridable Sub Online(ByVal CardInfo As Entity.StudentInfoEntity, ByVal OnLine As Entity.StuOnlineEntity, ByVal OnlineBLL As BLL.OnlineBLL)

    End Sub
End Class


判断用户是否存在子状态

''' <summary>
''' 判断用户是否注册子状态
''' </summary>
''' <remarks></remarks>
Public Class IsNull
    Inherits BLL.State

    Dim dataAccess As New Factory.DataAccess    '创建工厂
    Dim IStudentInfo As IDAL.IStudentInfo       '定义接口

    Public Overrides Sub Online(ByVal CardInfo As Entity.StudentInfoEntity, ByVal OnLine As Entity.StuOnlineEntity, ByVal OnlineBLL As BLL.OnlineBLL)
        IStudentInfo = dataAccess.CreateStudent '创建接口
        If IStudentInfo.SelectStudent(CardInfo).Rows.Count = 0 Then
            Throw New Exception("该用户尚未注册,请注册之后再进行上机操作")
        Else
            OnlineBLL.SetState(New IsOnline)    '如果注册,返回下个状态——判断用户是否上机子状态
            OnlineBLL.StuOnLine(CardInfo, OnLine, OnlineBLL)
        End If
    End Sub
End Class

判断用户是否上机子状态

''' <summary>
''' 判断用户是否上机子状态
''' </summary>
''' <remarks></remarks>
Public Class IsOnline
    Inherits BLL.State

    Dim dataAccess As New Factory.DataAccess     '创建工厂
    Dim IOnlineInfo As IDAL.IOnline              '定义接口

    Public Overrides Sub Online(ByVal CardInfo As Entity.StudentInfoEntity, ByVal OnLine As Entity.StuOnlineEntity, ByVal OnlineBLL As BLL.OnlineBLL)
        IOnlineInfo = dataAccess.CreateOnline    '创建接口
        If IOnlineInfo.SelectOnlineStu(OnLine).Rows.Count <> 0 Then
            Throw New Exception("该卡号正在正在上机,请更换其他卡号进行上机操作")
        Else
            OnlineBLL.SetState(New IsCashEnough)  '如果没有上机,转入到下个状态——判断用户余额是否充足
            OnlineBLL.StuOnLine(CardInfo, OnLine, OnlineBLL)
        End If
    End Sub
End Class


判断用户余额是否充足子状态


''' <summary>
''' 判断用户金额是否充足子状态
''' </summary>
''' <remarks></remarks>
Public Class IsCashEnough
    Inherits BLL.State

    Dim dataAccess As New Factory.DataAccess  '定义工厂
    Dim IStuInfo As IDAL.IStudentInfo         '定义接口
    Dim IBasicData As IDAL.IBasicDataset      '定义接口
    Public Overrides Sub Online(CardInfo As Entity.StudentInfoEntity, OnLine As Entity.StuOnlineEntity, OnlineBLL As OnlineBLL)
        IStuInfo = dataAccess.CreateStudent      '创建接口
        IBasicData = dataAccess.CreateBasicData  '创建接口
        '用户金额充足,进入下一个状态——判断用户是否添加信息成功,否则抛出异常
        If Trim(IStuInfo.SelectStudent(CardInfo).Rows(0).Item("Cash")) > Trim(IBasicData.SelectBasicData.Rows(0).Item("limitCash")) Then
            OnlineBLL.SetState(New IsAddOnline())
            OnlineBLL.StuOnLine(CardInfo, OnLine, OnlineBLL)
        Else
            Throw New Exception("用户余额不足,请充值之后再进行上机操作")

        End If
    End Sub
End Class

判断添加用户上机信息是否成功

''' <summary>
''' 重读状态基类,判断是否添加上机信息成功
''' </summary>
''' <remarks></remarks>
Public Class IsAddOnline
    Inherits BLL.State
    Dim dataAccess As New Factory.DataAccess
    Dim IOnline As IDAL.IOnline
    Dim IStudentInfo As IDAL.IStudentInfo
    Dim bolAddOnline As Boolean

    Public Overrides Sub Online(CardInfo As Entity.StudentInfoEntity, OnLine As Entity.StuOnlineEntity, OnlineBLL As OnlineBLL)
        IStudentInfo = dataAccess.CreateStudent
        Dim dtStuInfo As DataTable
        dtStuInfo = IStudentInfo.SelectStudent(CardInfo)

        OnLine.StuID = Trim(dtStuInfo.Rows(0).Item(1))
        OnLine.StuName = Trim(dtStuInfo.Rows(0).Item(2))
        OnLine.StuDepartment = Trim(dtStuInfo.Rows(0).Item(4))
        OnLine.StuSex = Trim(dtStuInfo.Rows(0).Item(3))
        OnLine.StuOndate = Date.Today '学生上机日期
        OnLine.StuOntime = TimeOfDay '学生上机时间
        OnLine.ComputerID = Environment.MachineName '学生上机机器号
        IOnline = dataAccess.CreateOnline
        bolAddOnline = IOnline.AddStuOnline(OnLine)
    End Sub

End Class

客户端窗体代码

  Dim onlinebll As New BLL.OnlineBLL

        Dim entityStuInfo As New Entity.StudentInfoEntity
        Dim entityLineInfo As New Entity.StuOnlineEntity
        entityStuInfo.StuCardID = Trim(txtCardID.Text)
        entityLineInfo.StuCardID = Trim(txtCardID.Text)

        Try
            If onlinebll.StuOnLine(entityStuInfo, entityLineInfo, onlinebll) = False Then
                MsgBox("用户上机失败", , "温馨提示")
            Else
                MsgBox("用户上机成功", , "温馨提示")
            End If
        Catch ex As Exception
            MsgBox(ex.Message.ToString, , "温馨提示")
        End Try

三、小结

对于状态模式,简而言之:可以用来解决复杂的业务逻辑判断,将纷繁复杂的业务判断分支以类的形式封装,根据具体的状态来执行不同的操作,从而实现了软件开发中的’开放——封闭原则‘,即保留了增加分支判断的可能性,也减少了因复杂分支修改过多的麻烦。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值