下机——观察者模式

       距离将设计模式已经是半个月了,记得师姐讲了一个观察者模式。不知道从哪里听到的,观察者模式很重要,当时师姐讲的时候也很认真的去听了听这一部分的内容。

      机房收费系统在周三结束的,当时唯一的一个遗憾就是在下机没有用到观察者模式,这次抱着好奇和学习的态度学习一下观察者模式。看了设计模式之后感觉这个部分好难呀,自己能不能实现真的很是成问题。就这样在鼓励和怀疑中前进的我,打破了内心的恐惧,真个机房收费系统经过自己的双手都敲完了,害怕这么一点点?坚定的走下去,头也不回的做下去。

        当然在做这个设计模式的时候,困难重重,主要就是全局没有把握好,所以在一些细节上不得不重写一些方法。在这次真心地是给以后一个很好的经验教训。

8月22号  天气:有些闷热   心情:有些低落

        这一天,是观察者经历了周三晚上,周四晚上的准备,渐渐的露出了成功的小嫩芽。

先看一下UML图:


       其中这里的具体的通知者只是单卡下机这个类,当然我们也可以有全部下机,强者下机,单卡下机这样三个不同的观察者。

       这里就写了一个有关于单卡下机的观察者模式,至于全部下机和强制下机,我们可以有三个通知者,根据通知者的状态不同,可以让观察者实现这些Update方法,但是全部下机,强制下机,这两个功能在我看来是相同的。都是基于单卡下机。所以这里单卡下机用观察这模式,那么在B层全部下机和强制下机只需要一个对单卡下机方法的循环便利就OK了。

接下来看一下代码:

'’尝试去做一个观察者模式
'’制作人:李雪
'’目的:下机中要更行卡状态,充值金额,消费金额这些信息
'’当下机的命令穿过来的时候
'’就通过一个通知者,去通知他旗下的观察者
'’告诉他们要下机了
'’所以这个功能  要哟:一个抽象观察者,一个抽象的通知者 ,具体的通知者,具体观察者

Imports Entity

'抽象出一个抽象的观察者
Public MustInherit Class outlieObserver
    Public MustOverride Function Update(ByVal cardcon As CardConsume) As Boolean
End Class

'抽象出一个抽象的通知者
Public MustInherit Class Subject


    '应该是定义个观察者的泛型数组集合,循环便利的去通知
    Private observers As IList(Of outlieObserver) = New List(Of outlieObserver)

    '增加观察者
    '不产生值得
    Public Sub Attach(ByVal observer As outlieObserver)
        observers.Add(observer)
    End Sub

    Private action As String 

    '通知者要做的事情就是通知
    Public Function Notify(ByVal cardcon As CardConsume) As Boolean
        Try

            'forEach顶一个元素o这个o的数据类型是Outlieobserver
            '同事这个实在集合observers中的
            For Each o As outlieObserver In observers
                o.Update(cardcon)
            Next
            Return True
        Catch ex As Exception
            Throw ex
        End Try


    End Function

End Class

'定义一个具体的通知者,主要就是给登记过的观察者进行通知
Public Class ConcreteSubject : Inherits Subject
    Private subjectState As String
    '具体被观察者的动态
    Public Property SubjectStation As String
        Get
            Return subjectState
        End Get
        Set(value As String)
            subjectState = value
        End Set
    End Property

End Class

'定义几个具体的观察者
'首先就是更新消费时间
'更新卡信息
'更新充值中的信息
Public Class outlineConsume : Inherits outlieObserver

    Private name As String
    Private observerState As String
    Private subject As ConcreteSubject

    Private factory As Factory.DataInquireFactory
    Public Sub New()
        factory = New Factory.DataInquireFactory
    End Sub

    '将自己加入到通知者的行列中区
    Public Sub outlineConsume(ByVal subject As ConcreteSubject, ByVal name As String)
        Me.subject = subject
        Me.name = name

    End Sub
    Public Overrides Function Update(ByVal cardcon As CardConsume) As Boolean

        Try
            observerState = subject.SubjectStation

            Dim consume As IDAL.ICard
            consume = factory.CreateCardInfo
            Return consume.UpdateConsume(cardcon)
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Property subjectConsume As ConcreteSubject
        Get
            Return subject
        End Get
        Set(value As ConcreteSubject)
            subject = value
        End Set
    End Property

End Class

'更新学生信息的月
Public Class CardInfo : Inherits outlieObserver

    Private subject As ConcreteSubject
    Private name As String

    Private factory As Factory.DataInquireFactory
    Public Sub New()
        factory = New Factory.DataInquireFactory
    End Sub

    Public Sub CardInfo(ByVal subject As ConcreteSubject, ByVal name As String)
        Me.subject = subject
        Me.name = name

    End Sub

    '更新学生卡中的信息
    Public Overrides Function Update(cardcon As Entity.CardConsume) As Boolean
        Try
            Dim card As New CardInfoEntity
            Dim mgr As New BLL.CardBLL
            card.cardId = cardcon.cardId
            card.status = "使用"
            cardcon.balance = mgr.CheckCardRecord(card).balance - cardcon.consumption
            Return mgr.UpdateRecharge(cardcon)
        Catch ex As Exception
            Throw ex
        End Try
    End Function
End Class

Public Class RechargeCard : Inherits outlieObserver

    Private subject As ConcreteSubject
    Private name As String

    Private factory As Factory.DataInquireFactory
    Public Sub New()
        factory = New Factory.DataInquireFactory
    End Sub

    Public Sub RechargeCard(ByVal subject As ConcreteSubject, ByVal name As String)
        Me.subject = subject
        Me.name = name

    End Sub

    '更新学生卡中的信息
    Public Overrides Function Update(cardcon As Entity.CardConsume) As Boolean
        Try
            Dim card As New CardInfoEntity
            Dim mgr As New BLL.CardBLL
            card.cardId = cardcon.cardId
            card.status = "使用"
            cardcon.balance = mgr.CheckCardRecord(card).balance - cardcon.consumption
            Return mgr.UpdateRecharge(cardcon)
        Catch ex As Exception
            Throw ex
        End Try
    End Function
End Class

U层代码,当然这也可以写到B层,看个人理解

       Dim outLine As New BLL.ConcreteSubject
        Dim cardConsume As New BLL.outlineConsume
        Dim cardInfo As New BLL.CardInfo
        Dim cardRecharge As New BLL.RechargeCard

        '每个实例化的对象都要实现各自的构造函数
        cardConsume.outlineConsume(outLine, "cardConsume")
        cardInfo.CardInfo(outLine, "cardInfo")
        cardRecharge.RechargeCard(outLine, "cardCharge")

        '添加观察者到通知者的集合中
        outLine.Attach(cardConsume)
        outLine.Attach(cardInfo)
        outLine.Attach(cardRecharge)

        '通知者告知观察者实现通知的放法
        outLine.Notify(cardcon)

这样就运行出来了,但是还有D层的代码,这里就不展示了。

       观察者的好处:抽象的通知者发出通知的时候,并不知道谁是他的观察者,这是在初始化的时候,谁加入了他,他就讲通知发给谁。不管加入多少,都不会影响代码的扩展性。同事任何一个具体的观察者也不会知道其他观察者的存在,做到了解耦合让耦合的双方都依赖抽象,做到了依赖倒转的原则。

看着这些代码,总觉得还可以再优化,还可以做得再好一些。

        这种感觉就像是米老师说的——盲人摸象。我第一次写代码,我就认为他就这样写,然后我写完了,他也运行了;当我回过头来,我发现他其实还可以简化一些,就把之间那些单纯面向过程的代码,逐渐的向面向对象靠近;之后呢学了三层,就发现用三层会更好,然后我敲完了,他也实现了,同时感觉三层真的是在很好的解耦合;之后学习了设计模式,发现设计模式可以让程序结构,维护性更好,然后我就又怀着一颗好奇的心去探索,然后他照样实现了。这也许就是程序的成长史,而这本成长史是永远都也写不完的。

他在成长,我们同时也在成长ing,在进步ing。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值