机房重构——下机(职责链模式+策略模式)

来源:互联网 发布:大数据运用案例 编辑:程序博客网 时间:2024/05/22 10:25

前言:

说起机房重构的下机自己都有点不好意思了,不想提起自己的那点“小事”。要做上下机的时候自己整个人都很不开心,感觉自己搞不定它们,有种压抑感,还略带了点小情绪,不想弄,其实都是自己把自己吓到了。只要静下心来,开开心心的去想思路,看代码,没有什么做不出来,学不会的。保持乐观的心态,比什么都重要。

策略模式:

它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。直白的说,策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。


职责链模式:

职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

好处:

接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需要保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用,大大降低了耦合度。可以随时随地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。

注意:

一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,所以需要事先考虑全面。


部分代码:

U层:

'下机    Private Sub btnDown_Click(sender As Object, e As EventArgs) Handles btnDown.Click        '判断卡号是否为空        If txtCardno.Text = "" Then            MsgBox("请输入卡号!", 0, "提示")            txtCardno.Focus()            Exit Sub        End If        '判断卡号是否存在或使用        Dim facade As New Facade.OnLineFacade        Dim card As New Entity.OnLineEntity        Dim table As DataTable        card.CardNo = txtCardno.Text.Trim        table = facade.SelectCardNo(card)        If table.Rows.Count = 0 Then            MsgBox("该卡号不存在!", 0, "提示")            txtCardno.Text = ""            txtCardno.Focus()            Exit Sub        Else            '判断卡号是否在上机(online)            Dim fac As New Facade.OnLineFacade            Dim line As New Entity.OnLineEntity            Dim onlinetable As New DataTable            line.CardNo = txtCardno.Text.Trim            onlinetable = fac.SelectoOn(line)            If onlinetable.Rows.Count = 0 Then                MsgBox("该卡未处于上机状态,无需下机!", 0, "提示")                txtCardno.Text = ""                txtCardno.Focus()                Exit Sub            Else                '获取T_Card表中对应上机卡号的金额和类型                Dim cash As String                Dim type As String                cash = table.Rows(0).Item(2)                type = table.Rows(0).Item(3).ToString.Trim                '获取上机时间                line.OnLineDate = Format(onlinetable.Rows(0).Item(3))                line.OnLineTime = onlinetable.Rows(0).Item(4).ToString                '给上机记录实体赋下机时间                line.OffLineDate = Format(DateTime.Now, "yyyy/MM/dd")                line.OffLineTime = Format(DateTime.Now, "HH:mm:ss")                '查询基本数据                Dim Basefac As New Facade.OnLineFacade                Dim data As New Entity.BaseDataEntity                Dim basetable As New DataTable                basetable = Basefac.SelectBaseData(data)                data.UnitTime = basetable.Rows(basetable.Rows.Count - 1).Item(3)                data.LeastTime = basetable.Rows(basetable.Rows.Count - 1).Item(4)                data.PrepareTime = basetable.Rows(basetable.Rows.Count - 1).Item(5)                '获取消费时间                Dim consumeTime As Integer                Dim BLLObject As New BLL.OnlineTimeCountBLL                consumeTime = BLLObject.costTime(data, line)                line.ConsumeTime = consumeTime                '根据获得的上机时间,利用策略模式计算消费金额                 If type = "固定用户" Then                    type = "Vip"                Else                    type = "Tmp"                End If                                          '实例化类OL_CashContextFacade,传入用户类型                Dim cashcontext As New BLL.OL_CashContextBLL(type)                '调用策略模式计算出余额并赋给consumecash                Dim consumecash As Single = cashcontext.GetResult(line.ConsumeTime)                '定义变量newcash,用于存放最新 的余额                Dim newcash As Single = CSng(cash.ToString) - CSng(consumecash)                '更新OnLine表,更新卡表的余额                line.ConsumeCash = consumecash                line.Cash = newcash                '获取学生表中的信息                Dim stufac As New Facade.OnLineFacade                Dim stuinfo As New Entity.OnLineEntity                Dim stutable As New DataTable                Dim flag As Boolean                stuinfo.CardNo = txtCardno.Text.Trim                stutable = stufac.SelectStu(stuinfo)                flag = facade.offline(line)                If flag = True Then                    MsgBox("下机成功!", 0, "提示")                    txtCardno.Text = line.CardNo                    txtType.Text = table.Rows(0).Item(3)                    txtStudentno.Text = onlinetable.Rows(0).Item(1)                    txtName.Text = stutable.Rows(0).Item(1)                    txtDepartment.Text = stutable.Rows(0).Item(3)                    txtSex.Text = stutable.Rows(0).Item(2)                    txtUpdate.Text = line.OnLineDate                    txtUptime.Text = line.OnLineTime                    txtDowndate.Text = line.OffLineDate                    txtDowntime.Text = line.OffLineTime                    txtCount.Text = newcash                    txtConsumetime.Text = consumeTime                    txtConsumcash.Text = consumecash                    line.IsOff = "下机"                    '统计上机人数,更新上机人数                    'line.CardNo = txtCardno.Text.Trim                    onlinetable = fac.SelectoOn(line)                    lblCount.Text = onlinetable.Rows.Count                Else                    MsgBox("下机失败!", 0, "提示")                End If            End If        End If    End Sub

B层:


职责链模式:

OL_TimeHandler

'定义一个处理请求的接口Public MustInherit Class OL_TimeHandler    Protected successor As OL_TimeHandler    Public Sub setsuccessor(ByVal successor As OL_TimeHandler)        Me.successor = successor '设置继承者    End Sub    Public MustOverride Function HandleTime(onlinetime As Integer) As Integer '处理请求的抽象类End Class
                                                                  

OL_PrepareTimeHandlerBLL

'准备时间处理类Public Class OL_PrepareTimeHandlerBLL : Inherits OL_TimeHandler    Private preparetime As Integer    Public Sub New(ByVal data As Entity.BaseDataEntity)        '构造函数,传入准备时间的值        Me.preparetime = CInt(data.PrepareTime)    End Sub    Public Overrides Function HandleTime(onlinetime As Integer) As Integer        If onlinetime <= preparetime Then            Return 0 'if 函数判断上机时间是否在处理范围内,在则返回0,不在转到下一个处理类        Else            Return successor.HandleTime(onlinetime) '转到下一位继承者        End If    End Function

OL_LeastTimeHandlerBLL

'至少上机时间处理类Public Class OL_LeastTimeHandlerBLL : Inherits OL_TimeHandler    Private leasttime As Integer    Public Sub New(ByVal data As BaseDataEntity)        Me.leasttime = CInt(data.LeastTime)    End Sub    Public Overrides Function HandleTime(onlinetime As Integer) As Integer        If onlinetime <= leasttime Then  '上机时间如果小于至少上机时间,返回上机时间            Return leasttime        Else  '否则转到下一位继承者            Return successor.HandleTime(onlinetime)        End If

OL_UnitTimeHandlerBLL

'单位时间处理类Public Class OL_UnitTimeHandlerBLL : Inherits OL_TimeHandler    Private unittime As Integer    Public Sub New(ByVal data As BaseDataEntity)        Me.unittime = CInt(data.UnitTime) 'CInt函数将数值转换成函数    End Sub    Public Overrides Function HandleTime(onlinetime As Integer) As Integer        Return Math.Abs(Int(-onlinetime / unittime)) * unittime        'int是将一个数值乡下取整为最接近的整数函数,取整函数        'abs函数返回指定数值的绝对值    End Function

OL_OnlineTimeCountBLL

'计算出上下机时间差,然后把结构返回给职责链处理Public Class OL_OnlineTimeCountBLL    Public Function costTime(data As Entity.BaseDataEntity, line As Entity.OnLineEntity) As Integer        '实例化类,通过构造函数,传递参数        Dim bPrepareTime As New OL_PrepareTimeHandlerBLL(data)        Dim bLeastTime As New OL_LeastTimeHandlerBLL(data)        Dim bStepTime As New OL_UnitTimeHandlerBLL(data)        bPrepareTime.setsuccessor(bLeastTime) '设置职责链继承者即后继承者        bLeastTime.setsuccessor(bStepTime)        '计算上下机时间差        Dim onlinetime As Integer        onlinetime = DateDiff("n", line.OnLineTime, line.OffLineTime) + DateDiff("n", line.OnLineDate, line.OffLineDate)        '职责链处理,返回上机时间        Return bPrepareTime.HandleTime(onlinetime)    End FunctionEnd Class

策略模式:

OL_CashContextBLL:

通过传入的卡的类型,对具体的固定用户或临时用户的处理算法进行选择

'通过传入的卡的类型,对具体的固定用户或临时用户的处理算法进行选择Imports System.Reflection'应用简单工厂模式,通过传入的卡的类型,来选择具体用哪个算法Public Class OL_CashContextBLL    Private cashsuper As OL_CashSuperBLL '定义抽象类    Public Sub New(ByVal Type As String)        '应用反射技术根据卡号类型自动选择应该实例化的类        Dim strInstance As String = "BLL.OL_Cash" + Type + "BLL"        cashsuper = CType(Assembly.Load("BLL").CreateInstance(strInstance), OL_CashSuperBLL)    End Sub    Public Function GetResult(ByVal onlinetime As String) As Single        '调用相关的消费处理类计算收费方法        Return cashsuper.GetConsumeCash(onlinetime)    End FunctionEnd Class

OL_CashSuperBLL:

定义算法的接口

'定义算法接口,抽象类Public MustInherit Class OL_CashSuperBLL    '根据上机时间、卡的类型,计算出消费金额,抽象方法。    Public MustOverride Function GetConsumeCash(ByVal online As Integer) As SingleEnd Class

OL_CashVipBLL:

计算固定用户消费金额

'具体策略类,计算固定用户消费金额,封装了具体的算法或行为,继承于OL_CashSuperBLLPublic Class OL_CashVipBLL : Inherits OL_CashSuperBLL    Dim queryBasedate As New BaseDataBLL '实例化查询基础数据    Dim ebasedate As New Entity.BaseDataEntity    Dim table As DataTable    Dim VipHourCash As Single '定义变量存放固定用户每小时费用    Public Overrides Function GetConsumeCash(onlinetime As Integer) As Single        table = queryBasedate.selectBaseData(ebasedate)        VipHourCash = table.Rows(table.Rows.Count - 1).Item(1) '查询数据库中对于固定用户的费用        Dim consumecash As Single        consumecash = CSng(onlinetime) * CSng(VipHourCash / 60) '计算消费金额        Return consumecash    End FunctionEnd Class

OL_CashTmpBLL:

计算临时用户消费金额

'计算临时用户消费金额Public Class OL_CashTmpBLL : Inherits OL_CashSuperBLL    Dim queryBaseDate As New BaseDataBLL '实例化查询基础数据    Dim ebasedate As New Entity.BaseDataEntity    Dim table As DataTable    Dim TemHourCash As Single '定义变量存放临时用户每小时费用    Public Overrides Function GetConsumeCash(onlinetime As Integer) As Single        '查询数据库中对于临时用户的费用        table = queryBaseDate.selectBaseData(ebasedate)        TemHourCash = table.Rows(table.Rows.Count - 1).Item(2)        '计算消费金额        Dim consumecash As Single        consumecash = CSng(onlinetime) * CSng(TemHourCash / 60)        Return consumecash    End FunctionEnd Class

D层:

利用存储过程pro_OffLine

 '下机    Public Function offinsert(ByVal line As Entity.OnLineEntity) As Boolean Implements IOnLine.offinsert        Dim sql As String        Dim sqlParams As SqlParameter() = {New SqlParameter("@cardno", line.CardNo),                                           New SqlParameter("@offdate", line.OffLineDate),                                           New SqlParameter("@offtime", line.OffLineTime),                                           New SqlParameter("@consumetime", line.ConsumeTime),                                           New SqlParameter("@consumecash", line.ConsumeCash),                                           New SqlParameter("@cash", line.Cash),                                           New SqlParameter("@isoff", "下机")                                        }        sql = "pro_OffLine"        Dim flag As Boolean        flag = sqlhelper.ExecAddDelUpdate(sql, CommandType.StoredProcedure, sqlParams)        Return flag    End FunctionEnd Class

存储过程:

CREATE PROCEDURE [dbo].[pro_OffLine]-- Add the parameters for the stored procedure here@cardno varchar(10),@offdate date,@offtime time(7),@consumetime varchar(10),@consumecash  numeric(18,1),@cash  varchar(50),@isoff char(5)ASBEGINupdate T_OnLine set offLineDate=@offdate ,offLineTime=@offtime,consumeTime=@consumetime,consumeCash=@consumecash ,isOff =@isoff where cardNo =@cardno update T_Card set cash=cash-@consumecash where cardNo=@cardno    END

注:创建好存储过程并执行后,再次打开存储过程create procedure将会变成alter procedure


总结:

在写这部分的时候,首先要理清楚思路,想好要判断哪些条件,做好准备工作,然后再动手写代码,不然写到一半很容易会思维混乱。也可以站在巨人的肩膀上,多多向大神们学习。(*^__^*) 嘻嘻……我也是。。。












0 0
原创粉丝点击