重構—多種方法實現學生下機,重構實現學生

來源:互聯網
上載者:User

重構—多種方法實現學生下機,重構實現學生

    在設計學生下機這個功能的時候,參考了很多部落格,覺得用職責鏈模式是很合適的,因為我們知道學生下機算消費餘額的時候是按照上機時間來算的,準備時間、至少上機時間,這就產生三種情況。但是雖然想到了,但是卻沒有具體的去實現,還是懶惰的原因吧,我就寫了一個SQL函數,這樣當學生下機時直接D層調用這個函數就可以了,直接返回消費時間、消費金額和餘額,函數代碼少,好實現,這就是當時的想法,可是驗收卻沒通過,偷懶是不行滴,還是好好的設計吧。

    首先我們要下機功能實現需要哪些條件,一個正在上機的卡號,這就需要我們首先驗證這個卡號是否存在、或者已經登出、或者未上機,這些搞清楚進行下一步,判斷消費時間——>下機時間-上機時間,看符合哪種收費方式,然後進行運算就好了。瞭解了需求,下面是我用觸發器+資料庫函數和職責鏈模式+策略模式分別實現的學生下機功能。

 

觸發器實現下機時間的自動填滿,消費時間的自動計算,餘額的自動計算和在卡表中的自動更新

 

<span style="font-size:24px;">USE [MyDB]GO/****** Object:  Trigger [dbo].[t_linelog]    Script Date: 02/13/2015 15:02:09 ******/SET ANSI_NULLS ONGOSETQUOTED_IDENTIFIER ONGOALTER trigger[dbo].[t_linelog]on [dbo].[Linelog]after insert, updateas --聲明變數declare @linelogidint,@cardno varchar(10),@consumetime int,@consumecash intselect@linelogid=id,@cardno =CardNO  frominsertedbegin --status改變則更新linelogif update(status) --更新下機時間update LinelogsetOffTime=GETDATE(),OffDate =GETDATE ()where ID =@linelogid --計算消費時間update LinelogsetConsumeTime=DateDiff("MINUTE", OnTime, OffTime) + DateDiff("MINUTE" , OnDate,OffDate)where ID =@linelogid --調用函數,計算消費金額update LinelogsetConsumeCash=dbo.f_ConsumeCash (@linelogid )where ID =@linelogid --更新卡中餘額update CardsetCash =card.Cash-Linelog .ConsumeCashfrom Card left joinLinelog on Card .CardNO =Linelog .CardNO where ID   =@linelogid  END</span>

資料庫Function Compute消費金額

 

<span style="font-size:24px;">USE [MyDB]GO/****** Object:  UserDefinedFunction[dbo].[f_ConsumeCash]    Script Date:02/12/2015 20:10:38 ******/SET ANSI_NULLS ONGOSETQUOTED_IDENTIFIER ONGOALTER function[dbo].[f_ConsumeCash](@linelogid int)returns intasbegin --聲明變數declare@preparetimeint,@leasttime int,@unittime int,@rate int,@tmprateint,@cardtypevarchar(10),@consumecashint,@cash int,@consumetimeint,@cardno varchar(10) --給變數賦值select@preparetime=PrepareTime,@leasttime=LeastTime,@unittime=UnitTime,@rate=Rate,@tmprate=tmpRatefrom BasicDataselect@cardtype=cardtype from Card where CardNO =@cardnoselect @consumetime=consumetime,@cardno=CardNO  fromLinelog  where ID =@linelogid --判斷使用者類別if @cardtype ='固定使用者'set @cash =@rateelseset @cash=@tmprate --計算消費金額if @consumetime<@preparetimeset @consumecash=0elseif @consumetime<@leasttimeset @consumecash=@leasttime  *@cashelseset @consumecash=(@consumetime/@unittime) *@cash --返回消費金額return @consumecashEndGO/****** Object:  UserDefinedFunction[dbo].[f_ConsumeCash]    Script Date:02/12/2015 20:10:38 ******/SET ANSI_NULLS ONGOSETQUOTED_IDENTIFIER ONGOALTER function[dbo].[f_ConsumeCash](@linelogid int)returns intasbegin --聲明變數declare@preparetimeint,@leasttime int,@unittime int,@rate int,@tmprateint,@cardtypevarchar(10),@consumecashint,@cash int,@consumetimeint,@cardno varchar(10) --給變數賦值select@preparetime=PrepareTime,@leasttime=LeastTime,@unittime=UnitTime,@rate=Rate,@tmprate=tmpRatefrom BasicDataselect@cardtype=cardtype from Card where CardNO =@cardnoselect @consumetime=consumetime,@cardno=CardNO  fromLinelog  where ID =@linelogid --判斷使用者類別if @cardtype ='固定使用者'set @cash =@rateelseset @cash=@tmprate --計算消費金額if @consumetime<@preparetimeset @consumecash=0elseif @consumetime<@leasttimeset @consumecash=@leasttime  *@cashelseset @consumecash=(@consumetime/@unittime) *@cash --返回消費金額return @consumecashEnd</span>
 

         下面是職責鏈+策略模式實現下機功能,首先再瞭解一下這兩個模式的結構圖,,是和My Code匹配的模式結構圖:



策略模式結構圖



職責鏈模式結構圖


職責鏈模式計算消費時間

 

U層調用代碼:

 

<span style="font-size:24px;">'職責鏈模式計算消費時間Dim ontimecount AsNew BLL.OnLineTimeCountBLLlinelog.ConsumeTime= ontimecount.CostTime(time, endatabasic:=BLL.DataBasicBLL.mydatabasic)</span>

(這裡的time是我在資料庫中利用觸發器得到的學生從上機到下機過程中所經曆的具體時間)


計算時間的函數,調用職責鏈模式,和外觀類似


<span style="font-size:24px;">Public ClassOnLineTimeCountBLL    Public m_TimeHanderBLL As TimeHanderBLL     ''' <summary>    ''' 職責鏈處理,上機時間的計算    ''' </summary>    ''' <param name="time  ">上機記錄實體</param>    ''' <param name="endatabasic">基本資料實體</param>    Public Function CostTime(ByVal time AsInteger, ByVal endatabasic As List(Of Entity.DataBasicEntity)) As Integer        Dim Bpreparetime As NewPrePareTimeHnaderBLL(endatabasic)        Dim Bleasttime As NewLeastTimeHanderBLL(endatabasic)        Dim Bunittime As NewUnitTimeHanderBLL(endatabasic)        Bpreparetime.SetSucessor(Bleasttime)        Bleasttime.SetSucessor(Bunittime)         Return Bpreparetime.HandleTime(time)    End FunctionEnd Class</span>

至少上機時間


<span style="font-size:24px;">Public ClassLeastTimeHanderBLL    Inherits TimeHanderBLL     Private leastTime As Integer     ''' <summary>    ''' 判斷上機時間是否小於至少上機時間,否則轉到下一位    ''' </summary>    ''' <paramname="time"></param>    Public Overrides Function HandleTime(ByValtime As Integer) As Integer        If time < leastTime Then            Return time        Else            Return successor.HandleTime(time)        End If     End Function     ''' <summary>    ''' 建構函式,傳入至少上機時間的值    ''' </summary>    ''' <paramname="endatabasic"></param>    Public Sub New(ByVal endatabasic As List(OfEntity.DataBasicEntity))        Me.leastTime =endatabasic.Item(0).LeastTime    End SubEnd Class</span>

準備時間


<span style="font-size:24px;">Public ClassPrePareTimeHnaderBLL    Inherits TimeHanderBLL     Private Preparetime As Integer    ''' <summary>    ''' 判斷上機時間是否小於準備時間,否則轉到下一位繼承者    ''' </summary>    ''' <paramname="time">時間</param>    Public Overrides Function HandleTime(ByValtime As Integer) As Integer        If time < Preparetime Then            Return time        Else            Return successor.HandleTime(time)        End If     End Function     ''' <summary>    ''' 建構函式,傳入準備時間的值    ''' </summary>    ''' <paramname="endatabasic"></param>    Public Sub New(ByVal endatabasic As List(OfEntity.DataBasicEntity))        Me.Preparetime =endatabasic.Item(0).PrepareTime    End SubEnd Class</span>

遞增時間


<span style="font-size:24px;">Public ClassUnitTimeHanderBLL    Inherits TimeHanderBLL     Private unitTime As Integer    Public m_TimeHanderBLL As TimeHanderBLL     ''' <summary>    ''' 大於至少上機時間,返回實際消費時間    ''' </summary>    ''' <paramname="time"></param>    Public Overrides Function HandleTime(ByValtime As Integer) As Integer        Return Math.Abs(Int(time / unitTime) +1)    End Function     ''' <summary>    ''' 建構函式,傳入單位遞增時間的值    ''' </summary>    ''' <paramname="endatabasic"></param>    Public Sub New(ByVal endatabasic As List(OfEntity.DataBasicEntity))        Me.unitTime =endatabasic.Item(0).UnitTime    End SubEnd Class</span>
 

策略模式計算消費金額

 

上下文Context,對一個策略進行引用

 

<span style="font-size:24px;">Public ClassCashContextBLL    Public myCashSuperBLL As CashSuperBLL     ''' <summary>    ''' 調用抽象類別的消費金額計算方法,得出消費金額    ''' </summary>    ''' <paramname="Time"></param>    Public Function GetResult(ByVal Time AsInteger) As Integer        Return myCashSuperBLL.CostCash(Time)    End Function     ''' <summary>    ''' 利用反射,根據卡號類型選擇要執行個體化的類    ''' </summary>    ''' <paramname="CardType">卡類型</param>    Public Sub New(ByVal CardType As String)        Dim strInstance As String ="BLL.Cash" + CardType + "BLL"        myCashSuperBLL =CType(Assembly.Load("BLL").CreateInstance(strInstance), CashSuperBLL)    End SubEnd Class</span>
 

具體的結算方法1

 

<span style="font-size:24px;">Public ClassCashFixBLL : Inherits CashSuperBLL     ''' <summary>    ''' 計算固定使用者消費金額    ''' </summary>    ''' <paramname="Time"></param>    Public Overrides Function CostCash(Time AsInteger) As Integer        Dim databasic As New List(OfEntity.DataBasicEntity)        Dim rate As Integer =BLL.DataBasicBLL.mydatabasic.Item(0).Rate        Return rate * Time    End FunctionEnd Class</span>

 具體的結算方法2

 

<span style="font-size:24px;">Public ClassCashTmpBLL : Inherits CashSuperBLL     ''' <summary>    ''' 計算臨時使用者消費金額    ''' </summary>    ''' <paramname="Time"></param>    Public Overrides Function CostCash(Time AsInteger) As Integer        Dim databasic As New List(OfEntity.DataBasicEntity)        Dim Tmprate As Integer =BLL.DataBasicBLL.mydatabasic.Item(0).tmpRate        Return Tmprate * Time    End FunctionEnd Class</span>

U層調用


'根據以上時間,應用策略模式計算消費金額Dim CardType AsString Select Case showmessage.Item(0).typeCase "固定使用者" CardType = "Fix" Case "臨時使用者" CardType = "Tmp" Case ElseCardType =""End Select'執行個體化類CashContextBLL,傳入使用者類型 Dim cashcontext As NewCashContextBLL(CardType) '調用策略模式計算出消費金額並賦值給上機記錄實體 checkcard.concash =cashcontext.GetResult(linelog.ConsumeTime)

    熟練的使用設計模式會讓我們更加容易編程,希望此文能幫到大家,不足之處還望多多指教。

 

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.