【机房重构】——观察者模式解决三种下机

【机房重构】——观察者模式解决三种下机,第1张

概述     引言   对于重构来说我们知道在机房收费这个系统中有三种下机——正常下机、强制所有下机、选择强制下机。在第一遍的时候我们就是在做完正常下机以后,然后复制代码来完成,在重构的时候有了设计模式作为基础,我们可以用观察者模式轻松搞定这三种下机。   基础篇  基本概念:观察者模式又叫做发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变 引言 对于重构来说我们知道在机房收费这个系统中有三种下机——正常下机、强制所有下机、选择强制下机。在第一遍的时候我们就是在做完正常下机以后,然后复制代码来完成,在重构的时候有了设计模式作为基础,我们可以用观察者模式轻松搞定这三种下机。 基础篇 基本概念:观察者模式又叫做发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化的时,会通知所有的观察者对象,是他们能够自动更新自己。 基本类图:
应用场景:当一个对象的改变需要同时改变其他对象,并且他不知道具体有多少对象有待改变时,应该考虑使用观察者模式。总的来讲,观察者模式所做的工作其实就是子啊解除耦合,让耦合的双方都依赖于抽象而不是依赖于具体,从而是得各自的变化都不会影响另一边的变化! 实战篇 在上面介绍了关于观察者模式的一些基本知识,现在就借助机房重构这个机会小试一把。因为我在下机的过程中需要进行如下判断:卡号是否存在、卡号是否正在上机、是否插入上机记录表等。这些都是每个下机都要判断的,所以用观察者模式来解决这个问题。 类图如下:
部分代码如下:
'**********************************************'说明:在下机的时候用观察者模式,抽象观察者'命名空间:BLL'机器名称:晓'创建日期:2015/1/4 22:50:10'作者:郑浩'版本号:V1.00'**********************************************Public Mustinherit Class SubjetBll    Private iList As IList(Of ObserverBLL) = New List(Of ObserverBLL)    ''' <summary>      ''' 添加观察者      ''' </summary>      ''' <param name="observer">抽象观察者类</param>      Public MustOverrIDe Sub Attach(ByVal observer As ObserverBLL)    ''' <summary>      ''' 去除观察者      ''' </summary>      ''' <param name="observer">抽象观察者类</param>      Public MustOverrIDe Sub Detach(ByVal observer As ObserverBLL)    ''' <summary>      ''' 通知观察者      ''' </summary>      Public MustOverrIDe Sub Notify(ByVal online As Entity.EN_CardInfo) End Class

'**********************************************'说明:抽象的观察者'命名空间:BLL'机器名称:晓'创建日期:2015/1/4 22:53:55'作者:郑浩'版本号:V1.00'**********************************************Public Mustinherit Class ObserverBLL    '定义一个抽象的更新的方法    Public MustOverrIDe Sub Update(ByVal online As Entity.EN_CardInfo)End Class

说明:上机的第一步检查卡号时候存在'命名空间:BLL'机器名称:晓'创建日期:2015/1/3 8:20:17'作者:郑浩'版本号:V1.00'**********************************************imports IDALimports BLL.OnlinestateBLLPublic Class IsExitCardNoBLL : inherits OnlinestateBLL    Public OverrIDes Sub online(ByVal cardinfo As Entity.EN_CardInfo,ByVal upline As BLL.UplineBLL)        Dim factory As New DAL.Factory        Dim Ionline As IOnOffline        Ionline = factory.CreateOnOffline        Dim dt As Datatable        dt = Ionline.CheckCardInfo(cardinfo)        '判断卡号是否存在        If (dt.Rows.Count = 0) Then            MsgBox("卡号不存在")        Else            cardinfo.Studentname = dt.Rows(0).Item(3)            cardinfo.Status = "正常上机"            upline.SetNextState(New BalanceStateBLL)            upline.CardOnline(cardinfo)        End If    End SubEnd Class

'**********************************************'说明:插入上机记录'命名空间:BLL'机器名称:晓'创建日期:2015/1/5 23:45:31'作者:郑浩'版本号:V1.00'**********************************************imports BLL.ObserverBLLimports IDALPublic Class OInsertOnlineRecord : inherits BLL.ObserverBLL    Public OverrIDes Sub Update(online As Entity.EN_CardInfo)        If Entity.PublicVariables.observeflag = "用户未上机" Then        Else            '首先在上机表中读取数据,然后赋给实体            Dim factory As New DAL.Factory            Dim Ionlining As IOnlining            Ionlining = factory.CreateOnlining            Dim dt As Datatable            dt = Ionlining.IsCardNolining(online)            '计算消费时间            Dim offdate As Date  '下机日期            offdate = Date.Today()            Dim offtime As String '下机时间            offtime = Date.Now.ToString("hh:mm:ss")            Dim spenttime As Double    '消费的时间            Dim realitytime As Double    '实际消费时间            Dim spentmoney As Integer    '消费金额            Dim type As String          '用户类型            Dim cardbalance As Integer            '调用获得基本数据方法来获得基本数据            Dim basicdatafactory As New DAL.Factory            Dim Ibasicdata As ISetBasicdata            Ibasicdata = basicdatafactory.CreateBasicdata            Dim table As Datatable            table = Ibasicdata.GetBasicdata()            '计算实际消费时间            realitytime = 0            spenttime = DateDiff(DateInterval.Minute,dt.Rows(0).Item(3),offdate) + DateDiff(DateInterval.Minute,cdate(dt.Rows(0).Item(4)),cdate(offtime))            '判断消费时间和准备时间的大小            If (spenttime < table.Rows(0).Item(5)) Then                realitytime = 0            ElseIf (spenttime < table.Rows(0).Item(4)) Then                realitytime = table.Rows(0).Item(4)            Else                realitytime = spenttime            End If            '调用检查卡号的方法,来获取用户类型和余额            Dim cardfactory As New DAL.Factory            Dim Ionline As IOnOffline            Ionline = cardfactory.CreateOnOffline            Dim carddt As Datatable            carddt = Ionline.CheckCardInfo(online)            type = carddt.Rows(0).Item(15)     '获得用户类型            cardbalance = carddt.Rows(0).Item(8)  '获得卡内余额            Dim basicdata As New Entity.EN_Basicdata            basicdata.FixPrice = table.Rows(0).Item(1)            basicdata.TempPrice = table.Rows(0).Item(2)            '调用CashFactory 来计算消费金额            Dim cashfactory As BLL.CashFactory = New CashFactory()            Dim csuper As BLL.CashSuper            csuper = cashfactory.CreateCashAccept(type)            spentmoney = csuper.AcceptCash(basicdata,realitytime)            '定义一个实体用来插入上机记录            Dim onlinerecord As New Entity.EN_CardInfo            onlinerecord.CardNo = dt.Rows(0).Item(1)            onlinerecord.Studentname = dt.Rows(0).Item(2)            onlinerecord.OnDate = dt.Rows(0).Item(3)            onlinerecord.OnTime = dt.Rows(0).Item(4)            onlinerecord.OffDate = offdate            onlinerecord.OffTime = offtime            onlinerecord.ConsumeTime = spenttime            onlinerecord.ConsumeMoney = spentmoney            onlinerecord.Balance = cardbalance - spentmoney            onlinerecord.WorkerComputer = System.Net.Dns.GetHostname().ToString()            onlinerecord.Status = online.Status            onlinerecord.Type = type            onlinerecord.Username = Entity.PublicVariables._username            '用于传给U层显示在文本框中            Entity.PublicVariables.onlinerecordinfo = onlinerecord            '调取学生表中的信息,用于填写U层的学生的基本信息            Dim Cfactory As New DAL.Factory            Dim CIonline As IOnOffline            CIonline = factory.CreateOnOffline            Dim Cdt As Datatable            Cdt = Ionline.CheckCardInfo(online)            '获得学生的基本信息后,赋给全局变量,然后传递给U层            Entity.PublicVariables.StudentBasicInfo = Cdt            '更新上机记录表中的数据            Dim Ionlinerecord As IOnOffline            Dim result As Integer            Ionlinerecord = factory.CreateOnOffline            result = Ionlinerecord.UpdatelineRecord(onlinerecord)            If result = 0 Then                MsgBox("更新上机记录失败")            End If        End If    End SubEnd Class
<pre name="code" >**********************************************'说明:具体的观察者'命名空间:Facade'机器名称:晓'创建日期:2015/1/6 0:23:04'作者:郑浩'版本号:V1.00'**********************************************Public Class FacadeFormalOnline    ''' <summary>    ''' 正常上机    ''' </summary>    ''' <param name="online"></param>    ''' <remarks></remarks>    Public Sub FormalOnline(ByVal online As Entity.EN_CardInfo)        Dim Fformalonline As New BLL.normalOffline        Fformalonline.Attach(New BLL.OCardisExist)        Fformalonline.Attach(New BLL.OCardisOnline)        Fformalonline.Attach(New BLL.OInsertOnlineRecord)        Fformalonline.Notify(online)    End SubEnd Class


  思考     我们都已经做过了一遍机房收费系统,我们根据需求会发现这样一个问题,当我们判断到卡号不存在时,会给出一个提醒“卡号不存在”,这时候后面的判断就不用进行了,直接退出,但是在观察这模式会自动遍历这些观察者,这就造成重复提示的缺陷,为了避免这个缺陷,我在实体层定义了一个全局变量用来在B层控制是否进行下一个判断。虽然达到做了目的,但是总感觉这样的办法不是最好的,这个问题正在研究中,如果哪位大神有好的想法,请留言提示!    小结    其实下机和上机时计算消费的判断思路差不多,但是为了更好的联系设计模式的知识,所以采用了不同的模式,在上机计算消费时采用了状态模式,详见【机房重构】——策略模式+简单工厂计算消费,在重构的时候主要是对前面学习的这些编程的思想和知识的一个灵活运用,所以在做的时候尽可能的采用不同思路和想法从多个方面来完成相应的功能,在这个阶段的运用没有对错之分,只有用过以后才能在下一次编程的时候更加灵活的运用它,所有希望同学能打开思路进行机房重构,Come On!!1           总结       

以上是内存溢出为你收集整理的【机房重构】——观察者模式解决三种下机全部内容,希望文章能够帮你解决【机房重构】——观察者模式解决三种下机所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1271243.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存