尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

设计模式21-备忘录模式:状态的保存与回退

设计模式21-备忘录模式:状态的保存与回退 备忘录模式把对象状态安全地存档撤销、草稿箱、游戏存档、流程回退都需要把对象某一刻的状态保存下来之后还能恢复。备忘录模式把这件事做成一个独立职责。一、痛点状态散落在对象内部外部不知道如何恢复一个文档编辑器支持“保存草稿”和“撤销”。最简单做法是把title、content、version三个字段逐个暴露出去Stringtitleeditor.getTitle();Stringcontenteditor.getContent();intversioneditor.getVersion();// 恢复时再逐个 set 回去这会让编辑器的内部结构暴露给调用方而且每次状态字段变化保存和恢复逻辑都要跟着改。备忘录模式的回答让原发器自己生成一个不可变的快照对象外部只负责保存和归还不知道快照内部长什么样。二、实现原发器 → 备忘录 → 负责人第一步定义备忘录publicrecordDocumentMemento(Stringtitle,Stringcontent,intversion){}备忘录不可变只作为状态的载体。第二步原发器负责创建和恢复快照publicclassDocumentEditor{privateStringtitle;privateStringcontent;privateintversion;publicDocumentEditor(Stringtitle,Stringcontent){this.titletitle;this.contentcontent;this.version1;}publicvoidmodify(Stringtitle,Stringcontent){this.titletitle;this.contentcontent;this.version;}publicDocumentMementosave(){returnnewDocumentMemento(title,content,version);}publicvoidrestore(DocumentMementomemento){this.titlememento.title();this.contentmemento.content();this.versionmemento.version();}publicStringsnapshot(){returntitletitle, contentcontent, versionversion;}}第三步负责人保存历史importjava.util.ArrayDeque;importjava.util.Deque;publicclassEditorHistory{privatefinalDequeDocumentMementohistorynewArrayDeque();publicvoidpush(DocumentMementomemento){history.push(memento);}publicDocumentMementopop(){returnhistory.pop();}}第四步客户端执行保存与撤销DocumentEditoreditornewDocumentEditor(标题,初稿);EditorHistoryhistorynewEditorHistory();history.push(editor.save());editor.modify(标题 V2,第二版);history.push(editor.save());editor.modify(标题 V3,第三版);editor.restore(history.pop());System.out.println(editor.snapshot());// V2editor.restore(history.pop());System.out.println(editor.snapshot());// 初稿三、备忘录的边界控制备忘录模式的关键在于“只有原发器知道快照内容”。工程上有两种常见做法方式做法优点窄接口负责人只看到不透明对象状态细节封装得最彻底宽接口备忘录暴露状态负责人可直接读写灵活但封装性较弱上面示例使用record暴露了状态适合状态简单、类内部可控的场景。如果状态复杂且需要严格封装可以设计成只有原发器能访问内部字段的私有类。四、工程化提醒注意内存大对象快照如果保存太多会造成内存压力需设置历史条数上限深拷贝问题备忘录中若包含可变对象保存时同样要处理深拷贝与命令模式配合命令模式负责“做什么”备忘录模式负责“状态怎么回退”两者常一起实现撤销/重做。小结备忘录模式一句话让对象自己保存自己的过去。它把快照的创建与恢复收口到原发器内部外部只负责“存起来”和“拿回来”既支持回退也保护了对象状态封装。
返回列表