当前位置: 首页 > 科技观察

设计模式系列-备忘录模式

时间:2023-03-23 11:02:52 科技观察

模式定义在不破坏封装的情况下捕获对象的内部状态,并将该状态保存在对象外部,以便以后需要时可以将对象恢复到原来的状态。这种模式也称为快照模式。模板实现如下:Caretakercr=newCaretaker();or.setState("S0");System.out.println("Initialstate:"+or.getState());cr.setMemento(or.createMemento());//保存状态or.setState("S1");System.out.println("新状态:"+or.getState());or.restoreMemento(cr.getMemento());//恢复状态System.out.println("恢复状态:"+or.getState());}}//MemoclassMemento{privateStringstate;publicMemento(Stringstate){this.state=state;}publicvoidsetState(Stringstate){this.state=state;}publicStringgetState(){returnstate;}}//OriginatorclassOriginator{privateStringstate;publicvoidsetState(Stringstate){this.state=state;}publicStringgetState(){returnstate;}publicMementocreateMemento(){returnnewMemento(state);}publicvoidrestoreMemento(Mementom){this.setState(m.getState());}}//管理类Caretaker{privateMementomemento;publicvoidsetMemento(Mementom){memento=m;}publicMementogetMemento(){returnmemento;}}输出结果如下:初始状态:S0新状态:S1恢复状态:S0解决的问题memento方式可以记录一个对象的内部状态,当用户后悔时,可以撤销当前操作,将数据恢复到原来的状态。每个人犯错的时候,都希望有一种“后悔药”可以弥补自己的错误,让自己重新开始,但现实是残酷的。在计算机应用中,客户也经常犯错误。我们能否为他们提供“后悔药”?当然是可以的,也是必须的。这个功能是通过“备忘录模式”来实现的。模式构成备忘录模式的核心是设计备忘录类和用于管理备忘录的管理器类。示例说明示例概述以游戏存档为例,看看如何使用备忘录模式实现使用步骤步骤一:定义备忘录角色,用于存储角色状态。classRoleStateMemento{privateintvit;//生命力privateintatk;//攻击privateintdef;//防御publicRoleStateMemento(intvit,intatk,intdef){this.vit=vit;this.atk=atk;this.def=def;}publicintgetVit(){returnvit;}publicvoidsetVit(intvit){this.vit=vit;}publicintgetAtk(){returnatk;}publicvoidsetAtk(intatk){this.atk=atk;}publicintgetDef(){returndef;}publicvoidsetDef(intdef){this.def=def;}}第二步:定义发起者角色(当前游戏角色),记录当前游戏角色的生命力、攻击力和防御力。使用saveState()方法保存当前状态,使用recoveryState()方法恢复角色状态。classGameRole{privateintvit;//活力privateintatk;//攻击privateintdef;//防御.atk=atk;}publicintgetDef(){returndef;}publicvoidsetDef(intdef){this.def=def;}//状态显示publicvoidstateDisplay(){System.out.println("角色当前状态:");系统。out.println("体力:"+this.vit);System.out.println("攻击力:"+this.atk);System.out.println("防御力:"+this.def);System.out.println("----------------");}//获取初始状态publicvoidgetInitState(){this.vit=100;this.atk=100;this.def=100;}//战斗结束后publicvoidfight(){this.vit=0;this.atk=0;this.def=0;}//保存角色状态publicRoleStateMementosaveState(){return(newRoleStateMemento(vit,atk,def));}//恢复角色状态publicvoidrecoveryState(RoleStateMementomemento){this.vit=memento.getVit();this.atk=memento.getAtk();this.def=memento.getDef();}}第三步:定义管理角色的角色,角色状态管理器classRoleStateCaretaker{privateRoleStateMementomemento;ppublicRoleStateMementogetMemento(){returnmemento;}publicvoidsetMemento(RoleStateMementomemento){this.memento=memento;}}第四步:测试输出publicclassMementoPattern{//逻辑大概是打boss前保存,boss失败publicstaticvoidmain(String[]args){//打boss之前GameRolegameRole=newGameRole();gameRole.getInitState();gameRole.stateDisplay();//保存进度RoleStateCaretakercaretaker=newRoleStateCaretaker();caretaker.setMemento(gameRole.saveState());//打boss游戏角色失败。fight();gameRole.stateDisplay();//恢复状态gameRole.recoveryState(caretaker.getMemento());gameRole.stateDisplay();}}输出角色当前状态:体力:100攻击力:100防御力量:100--------------角色当前状态:体力:0攻击力:0防御力:0-----------------角色现状:体力:100攻击力:100防御力:100优点备忘录模式是一种对象行为模式,其主要优点如下:提供了一种可以恢复状态的机制。当用户需要时,更方便地将数据恢复到某个历史状态。实现了内部状态的封装。除了创建它的发起者之外,没有其他对象可以访问此状态信息。简化的启动人类。发起者无需管理和保存其内部状态的单独备份,所有状态信息保存在备忘录中,由管理者管理,符合单一责任原则。缺点是消耗资源多。如果要保存的内部状态信息过多或者非常频繁,会占用比较大的内存资源。注意事项为了遵守迪米特定律,需要有一个管理备忘录的类。不要在经常创建备份的场景中使用备忘录模式。为了节省内存,可以使用PrototypeMode+MemoModeApplicationScenarios需要保存和恢复数据的相关场景提供回滚操作,比如ctrl+z、浏览器后退键、Backspace键等。在memento模式下,有单态备份和多态备份的例子。可以与原型模式结合使用。memo模式下,通过定义“memo”来备份“发起人”信息,prototype模式的clone()方法具有自备份功能,所以如果发起者实现了Cloneable接口,则具有该功能备份自己。Atthistime可以删除备忘录类,其结构如下:源码中的应用#Springorg.springframework.binding.message.StateManageableMessageContextStateManageableMessageContext部分源码publicinterfaceStateManageableMessageContextextendsMessageContext{/***Createaserializablememento,ortokenrepresentingasnapshotoftheinternalstateofthismessagecontext.*@returnthemessagesmemento*/publicSerializablecreateMessagesMemento();/***根据提供的主题设置此上下文的状态。Afterthiscall,themessagesinthiscontextwillmatch*whatisencapsulatedinsidethememento.Anypreviousstatewillbeoverridden.*@parammessagesMementothemessagesmemento*/publicvoidrestoreMessages(SerializablemessagesMemento);/***Configurethemessagesourceusedtoresolvemessagesaddedtothiscontext.Maybesetatanytimetochangehow*codedmessagesareresolved.*@parammessageSourcethemessagesource*@seeMessageContext#addMessage(MessageResolver)*/publicvoidsetMessageSource(MessageSourcemessageSource);}PS:以上代码提交在Github上:https://github.com/Niuh-Study/niuh-designpatterns.git

最新推荐
猜你喜欢