實戰練習之 狀態模式

2021-06-19 01:58:59 字數 4447 閱讀 3765

在第一遍學習大話設計模式的時候,寫過關於狀態模式的部落格。不過那個時候的素材主要來自於課本,理解的內容也是書上的例子,以「看懂」為主要目的。但是在這次機房收費系統合作版的實戰中,我需要以「會用」為主要目的了,當然,理解的也會有所深刻。

此次我把狀態模式加在上學生下機處,主要為了計算消費金額。大致思路為:(此種思路主要針對於網咖使用的收費系統,因為學校機房可以玩通宵的還是比較少的。)首先,將上機狀態分為兩種:一種是白天狀態,另一種那個就是夜間狀態。夜間狀態的消費金額為固定,白天狀態的消費金額則是變化的,因消費時間和使用者型別而異。下面是機房收費系統中狀態模式的結構圖:

**如下:

一、抽象狀態類:此類定義乙個介面,封裝了與

context

中乙個特定狀態有關的行為。

''' ''' 抽像狀態類

'''

public mustinheritclass state

''' ''' 消費金額

'''

''' 傳遞過來上機時間。

public mustoverride function handle(byvalenstudent as entity.lineentity, byval context as context) as string

end class

二、狀態子類:夜間狀態,此處取出上機時間中的小時值,判斷使用者處於哪兒中狀態,如果符合當前子類狀態,則

需要指定下一狀態)

''' ''' 夜間狀態'''

public classnightstate

inherits bll.state

''' ''' 消費金額

'''

''' 傳遞過來上機時間。

''' 狀態的作用物件。

public overloads overrides functionhandle(enstudent as entity.lineentity, context as context) as string

dim spendmoney as string

dim ontime as system.datetime

dim hour as integer = ontime.hour

'取出上機時間中的小時值

ontime =system.datetime.parse(cstr(enstudent.ontime))

'判斷使用者是何時上機,如果是夜間上機的話,返回「夜間模式」

if hour < 6 or hour > 22 then

return "夜間模式"

else

context.setstate(new daystate)

end if

end function

end class

三、狀態子類:同上

''' ''' 白天模式'''

public classdaystate

inherits bll.state

''' ''' 消費金額

'''

''' 傳遞過來上機時間。

''' 狀態作用物件

public overloads overrides functionhandle(enstudent as entity.lineentity, context as context) as string

dim ontime as system.datetime

dim hour as integer = ontime.hour

'取出上機時間中的小時值

ontime =system.datetime.parse(cstr(enstudent.ontime))

'判斷使用者是何時上機,如果是夜間上機的話,消費時間為實際消費時間,消費金額固定為15元

if hour > 6 and hour < 22 then

return "白天模式"

else

context.setstate(new nightstate)

end if

end function

end class

四、context。首先,它需要定義乙個初始狀態,再此我們定義

daystate

也就是白天模式為預設初始狀態,並且需要設定乙個「鐘點」屬性,用來判斷當前狀態和設定最新狀態。

''' '''context類,定義當前的狀態

'''

'''public class context

private currentstate as state

'定義context的初始狀態--為白天模式

public sub new(byval state as state)

currentstate = new daystate

end sub

private hour as double

'"鐘點"屬性,狀態轉換的依據

public property _hour() as double

getreturn hour

end get

set(byval value as double)

hour = value

end set

end property

''' ''' 設定工作狀態

'''

''' 工作狀態

'''

public sub setstate(byval state as state)

currentstate = state

end sub

''' ''' 維護乙個concretestate子類的例項,這個例項定義當前的狀態。

'''

public function request(byval enstudent asentity.lineentity) as string

'對請求做處理,並設定下一狀態

return currentstate.handle(enstudent,me)

end function

end class

五、客戶端**:此處,例項化

context

類,並且設定

context

的初始狀態為:白天

狀態,然後根據

u層傳來的學生上機資訊實體類中的上機時間,來判斷屬於那種狀態。如果是白天狀態,則呼叫策略模式中的相應具體演算法類(此處咱不強調),根據消費時間和使用者型別,計算出消費金額;反之如果是夜間狀態,暫定消費金額固定,為

15元。

''' ''' 不同的使用者收取的金額。

'''

''' 學生上機實體類

public function getresutl(byval enstudentas entity.lineentity) as double

dim daystate as new daystate

dim statetype as newcontext(daystate) '設定context的初始狀態為:白天模式

dim nowstate as string

dim spendmoney as double

nowstate =statetype.request(enstudent) '根據實體中的上機時間屬性,來判斷狀態型別

'如果是夜間模式,消費金額恒為15元;如果為白天模式,消費金額依據卡型別不同而不同

if nowstate = "白天模式" then

'固定使用者呼叫fixuser具體演算法類

ifenstudent.cardtype = "固定使用者" then

dim fixuser as new fixuser

spendmoney =fixuser.acceptcash(enstudent)

else

'臨時使用者呼叫tempuser具體演算法類

dim tempuser as new tempuser

spendmoney =tempuser.acceptcash(enstudent)

end if

else

spendmoney = 15

end if

return spendmoney

end function

這樣,我們可以實現**擴充套件的靈活性,我們可以通過增加不同的狀態子類來增加不同的狀態,不再需要過醜和過長的分支判斷了。當然了,這樣也實現了好**的可開放

-封閉原則。

設計模式 狀態模式練習

某紙牌遊戲軟體中,人物角色具有人門級 primary 熟練級 secondary 高手紹 professional 和骨灰級 final 四種等級,角色的等級與其積分相對應,遊戲勝利將增加和分,失敗則扣除積分。人門級具有最基本的遊戲功能 play 熟練級增加丁遊戲勝利積分加倍功能doublescor...

狀態機模式實戰

最近在為澳洲一家保險公司做web應用,在乙個收集使用者位址資訊的頁面中,我遇到了乙個問題 1.當使用者輸入正確的位址,通過驗證。2.當使用者第一次輸入錯誤的位址,不通過。3.當使用者第二次輸入,不論正確與否,都將通過。當面對這樣的需求的時候,我立馬有了解決方案,首先要有乙個全域性變數來儲存他輸入的位...

Android 設計模式實戰筆記 狀態模式

當乙個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類 1.乙個物件的行為取決於它的狀態,並且它的狀態必須在執行時根據狀態改變它的行為 2.中包含大量與物件狀態有關的條件語句,例如,乙個操作中含有龐大的多分支語句 if else且這些分支依賴該物件的狀態 實戰使用者登入系統 取在普通...