本篇内容主要讲解“java备忘录模式怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java备忘录模式怎么实现”吧!
备忘录模式又称为快照模式或令牌模式,属于行为型模式。
它是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。简而言之:允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
它提供一种类似“后悔药”的机制,通过存储系统各个历史状态的快照,使得可以在任一时刻将系统回滚到某一个历史状态。
1.需要保存历史快照的场景 2.希望在对象之外保存状态,且除了自己其他类对象无法访问状态保存具体内容
应用场景举例:代码版本控制,游戏存档功能,数据库的事务管理等
假如有一款编辑器应用程序,程序在执行任何操作前记录所有的对象状态, 并将其保存下来。 当用户此后需要撤销某个操作时, 程序将从历史记录中获取最近的快照, 然后使用它来恢复所有对象的状态。
优点:
1.简化发起人实体类Originator职责,隔离状态存储与获取,实现了信息的封装,客户端无需关心状态的保存细节 2.提供状态回滚功能:给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
缺点:
1.消耗资源:如果需要保存的状态过多时,每一次保存都会消耗很多内存。
备忘录模式主要包含三种角色:
1.发起人角色(Originator)
负责创建一个备忘录,记录自身需要保存的状态;具备状态回滚功能。
2.备忘录角色(Memento)
用于存储Originator的内部状态,且可以防止Originator以外的对象进行访问。
3.备忘录管理员角色(Caretaker)
负责存储,提供管理备忘录(Memento),无法对备忘录内容进行操作和访问。
备忘录模式本质是从发起人实体类(Originator)隔离存储功能,降低实体类的职责。同时由于存储信息(Memento)独立,且存储信息的实体交由管理类(Caretaker)管理,则可以通过为管理类扩展额外的功能对存储信息进行扩展操作。
@Data public class Memento { private String state; public Memento(String state){ this.state = state; } }
@Data public class Originator { /** * 内部状态 */ private String state; /** * 创建一个备忘录 * * @return */ public Memento createMemento() { return new Memento(this.state); } /** * 从备忘录恢复 * * @param memento */ public void restoreMemento(Memento memento) { this.setState(memento.getState()); } }
public class Caretaker { private Memento memento; public Memento getMemento() { return this.memento; } public void storeMemento(Memento memento) { this.memento = memento; } }
public static void main(String[] args) { // 创建发起人角色 Originator originator = new Originator(); // 创建备忘录管理员 Caretaker caretaker = new Caretaker(); // 设置存储状态 originator.setState("A"); // 存储发起人创建的备忘录 caretaker.storeMemento(originator.createMemento()); System.out.println("设置存储状态:" + originator.getState()); // 设置存储状态 originator.setState("B"); System.out.println("更新存储状态:" + originator.getState()); // 备忘录进行回滚 originator.restoreMemento(caretaker.getMemento()); System.out.println("回滚到设置的状态:" + originator.getState()); }
设置存储状态:A 更新存储状态:B 回滚到设置的状态:A
@Data @ToString public class CodeMemento { /** * 提交内容 */ private String content; /** * 提交备注 */ private String remark; public CodeMemento(String content, String remark) { this.content = content; this.remark = remark; } }
@Data @ToString public class GitOriginator { /** * 提交内容 */ private String content; /** * 提交备注 */ private String remark; public GitOriginator(String content, String remark) { this.content = content; this.remark = remark; } /** * 提交代码 * * @return */ public CodeMemento saveToMemento() { CodeMemento codeMemento = new CodeMemento(this.content, this.remark); return codeMemento; } /** * 恢复代码 * * @param codeMemento */ public void undoFromMemento(CodeMemento codeMemento) { this.content = codeMemento.getContent(); this.remark = codeMemento.getRemark(); } }
public class GitCaretaker { /** * 使用栈来存储备忘录,最新的备忘录排在栈顶 */ private final Stack<CodeMemento> STACK = new Stack<CodeMemento>(); public CodeMemento getMemento(){ // 移除栈顶的备忘录 CodeMemento codeMemento = STACK.pop(); return codeMemento; } public void addMemento(CodeMemento codeMemento){ // 将备忘录压入栈顶 STACK.push(codeMemento); } }
public static void main(String[] args) { System.out.println("--------------------第一次创建代码--------------------------------"); // 创建一个备忘录管理者 GitCaretaker gitCaretaker = new GitCaretaker(); // 创建一个备忘录发起人 GitOriginator gitOriginator = new GitOriginator("write code 1", "第一次提交代码备注"); // 创建一个备忘录 CodeMemento codeMemento = gitOriginator.saveToMemento(); // 将备忘录压入栈顶 gitCaretaker.addMemento(codeMemento); System.out.println("第一次提交代码完成。代码:" + gitOriginator.getContent() + " 备注:" + gitOriginator.getRemark()); System.out.println("--------------------第二次修改代码--------------------------------"); gitOriginator.setContent("write code 2"); gitOriginator.setRemark("第二次提交代码备注"); codeMemento = gitOriginator.saveToMemento(); gitCaretaker.addMemento(codeMemento); System.out.println("第二次提交代码完成。代码:" + gitOriginator.getContent() + " 备注:" + gitOriginator.getRemark()); System.out.println("--------------------第三次修改代码--------------------------------"); gitOriginator.setContent("write code 3"); System.out.println("第三次修改代码。代码:" + gitOriginator.getContent()); System.out.println("--------------------在第三次修改代码基础上回退到第二次提交--------------------------------"); codeMemento = gitCaretaker.getMemento(); gitOriginator.undoFromMemento(codeMemento); System.out.println("回退到第二次提交完成。代码:" + gitOriginator.getContent() + " 备注:" + gitOriginator.getRemark()); System.out.println("--------------------在第二次修改代码基础上回退到第一次提交--------------------------------"); codeMemento = gitCaretaker.getMemento(); gitOriginator.undoFromMemento(codeMemento); System.out.println("回退到第一次提交完成。代码:" + gitOriginator.getContent() + " 备注:" + gitOriginator.getRemark()); }
--------------------第一次创建代码-------------------------------- 第一次提交代码完成。代码:write code 1 备注:第一次提交代码备注 --------------------第二次修改代码-------------------------------- 第二次提交代码完成。代码:write code 2 备注:第二次提交代码备注 --------------------第三次修改代码-------------------------------- 第三次修改代码。代码:write code 3 --------------------在第三次修改代码基础上回退到第二次提交-------------------------------- 回退到第二次提交完成。代码:write code 2 备注:第二次提交代码备注 --------------------在第二次修改代码基础上回退到第一次提交-------------------------------- 回退到第一次提交完成。代码:write code 1 备注:第一次提交代码备注
到此,相信大家对“java备忘录模式怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。