第十四章 Caché 設計模式 備忘錄模式

文章目錄

第十四章 Caché 設計模式 備忘錄模式

定義

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象回覆到原先保存的狀態。

使用場景

  • 備忘錄模式比較適用於功能比較複雜的,但需要維護或記錄屬性歷史的類,或者需要保存的屬性只是衆多屬性中的一小部分時,Originator可以根據保存的Memento信息還原到前一狀態。
  • 如果在某個系統中使用命令模式時,需要實現命令的撤銷功能,那麼命令模式可以使用備忘錄模式來儲存可撤銷操作的狀態。
  • 當角色的狀態改變的時候,有可能在這個狀態無效,這時候就可以使用暫時儲存起來的備忘錄將狀態復原。

結構圖

描述

玩遊戲時,角色有體力值,攻擊力,防禦力。保存這些狀態並恢復。

完整示例

角色類

Class PHA.YX.Design.Memento.GameRole Extends %RegisteredObject
{

Property vitality As %Integer [ Private ];

Method vitalityGet() As %Integer [ ServerOnly = 1 ]
{
	Quit i%vitality
}

Method vitalitySet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%vitality = Arg
	Quit $$$OK
}

Property attact As %Integer [ Private ];

Method attactGet() As %Integer [ ServerOnly = 1 ]
{
	Quit i%attact
}

Method attactSet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%attact = Arg
	Quit $$$OK
}

Property defense As %Integer [ Private ];

Method defenseGet() As %Integer [ ServerOnly = 1 ]
{
	
	Quit i%defense
}

Method defenseSet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%defense = Arg
	Quit $$$OK
}

Method StateDisplay()
{
	w "當前角色狀態:",!
	w "體力:" _ ..vitalityGet(),!
	w "攻擊力:" _ ..attactGet(),!
	w "防禦力:" _ ..defenseGet(),!
	w "",!
}

Method GetInitState()
{
	s ..vitality = 100
	s ..attact = 100
	s ..defense = 100
}

Method Fight()
{
	s ..vitality = 0
	s ..attact = 0
	s ..defense = 0
}

Method SaveState() As RoleStateMemento
{
	q ##class(RoleStateMemento).%New(..vitality, ..attact, ..defense)
}

Method RecoveryState(memento As RoleStateMemento)
{
	s ..vitality = memento.vitalityGet()
	s ..attact = memento.attactGet()
	s ..defense = memento.defenseGet()
}

}

儲存類

Class PHA.YX.Design.Memento.RoleStateMemento Extends %RegisteredObject
{

Property vitality As %Integer [ Private ];

Method vitalityGet() As %Integer [ ServerOnly = 1 ]
{
	Quit i%vitality
}

Method vitalitySet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%vitality = Arg
	Quit $$$OK
}

Property attact As %Integer [ Private ];

Method attactGet() As %Integer [ ServerOnly = 1 ]
{
	Quit i%attact
}

Method attactSet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%attact = Arg
	Quit $$$OK
}

Property defense As %Integer [ Private ];

Method defenseGet() As %Integer [ ServerOnly = 1 ]
{
	
	Quit i%defense
}

Method defenseSet(Arg As %Integer) As %Status [ ServerOnly = 1 ]
{
	s i%defense = Arg
	Quit $$$OK
}

Method %OnNew(vitality, attact, defense) As %Status [ Private, ServerOnly = 1 ]
{
	s ..vitality = vitality
	s ..attact = attact
	s ..defense = defense
	Quit $$$OK
}

}

管理類

Class PHA.YX.Design.Memento.RoleStateCaretaker Extends %RegisteredObject
{

Property memento As RoleStateMemento [ Private ];

Method mementoGet() As RoleStateMemento [ ServerOnly = 1 ]
{
	Quit i%memento
}

Method mementoSet(Arg As RoleStateMemento) As %Status [ ServerOnly = 1 ]
{
	s i%memento = Arg
	Quit $$$OK
}

}

調用

/// d ##class(PHA.YX.Design.Program).Memento() 
ClassMethod Memento()
{
	/*進入遊戲*/
	#dim yx as PHA.YX.Design.Memento.GameRole
	s yx = ##class(PHA.YX.Design.Memento.GameRole).%New()
	d yx.GetInitState()
	d yx.StateDisplay()
	
	/*保存進度*/
	#dim state as PHA.YX.Design.Memento.RoleStateCaretaker
	s state = ##class(PHA.YX.Design.Memento.RoleStateCaretaker).%New()
	d state.mementoSet(yx.SaveState())
	
	/*大戰BOSS,損耗嚴重*/
	d yx.Fight()
	d yx.StateDisplay()
	
	/*恢復之前狀態*/
	d yx.RecoveryState(state.mementoGet())
	d yx.StateDisplay()
}
DHC-APP>d ##class(PHA.YX.Design.Program).Memento()
當前角色狀態:
體力:100
攻擊力:100
防禦力:100
 
當前角色狀態:
體力:0
攻擊力:0
防禦力:0
 
當前角色狀態:
體力:100
攻擊力:100
防禦力:100

思考

記錄聽歌時的狀態(歌曲名稱,百分比,播放模式)。感興趣的同學實現後可以發我一起參考下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章