又称为快照模式或令牌模式, 是指在不破坏封装的前提下, 捕获一个对象的内部状态,
并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
特征: 后悔药;属于行为型模式
使用场景
1、需要保存历史快照的场景
2 希望在对象之外保存状态, 且除了自己其他类对象无法访问状态保存具体内容
public class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; } public void setState(String state) { this.state = state; } }
public class Originator { private String state; public String getState() { return state; } public void setState(String state) { this.state = 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 memento; } public void setMemento(Memento memento) { this.memento = memento; } public void storeMemento(Memento memento) { this.memento = memento; } }
public static void main(String[] args) { // 来一个发起人 Originator originator = new Originator(); // 来一个备忘录管理员 Caretaker caretaker = new Caretaker(); // 管理员存储发起人的备忘录 caretaker.storeMemento(originator.createMemento()); // 发起人从管理员获取备忘录进行回滚 originator.restoreMemento(caretaker.getMemento()); }
=================================================================================
public class ArticleMemento { private String title; private String content; private String imgs; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getImgs() { return imgs; } public void setImgs(String imgs) { this.imgs = imgs; } public ArticleMemento(String title, String content, String imgs) { this.title = title; this.content = content; this.imgs = imgs; } @Override public String toString() { return "ArticleMemento{" + "title='" + title + '\'' + ", content='" + content + '\'' + ", imgs='" + imgs + '\'' + '}'; } }
public class Editor { private String title; private String content; private String imgs; public Editor(String title, String content, String imgs) { this.title = title; this.content = content; this.imgs = imgs; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getImgs() { return imgs; } public void setImgs(String imgs) { this.imgs = imgs; } /** * 创建一个备忘录 * @return */ public ArticleMemento saveToMemento(){ ArticleMemento articleMemento = new ArticleMemento(title, content, imgs); return articleMemento; } /** * 从备忘录回复 * @param articleMemento */ public void undoFromMemento(ArticleMemento articleMemento) { this.title = articleMemento.getTitle(); this.content = articleMemento.getContent(); this.imgs = articleMemento.getImgs(); } @Override public String toString() { return "Editor{" + "title='" + title + '\'' + ", content='" + content + '\'' + ", imgs='" + imgs + '\'' + '}'; } }
public class DraftsBox { private final Stack<ArticleMemento> STACK = new Stack<>(); public ArticleMemento getMemento() { ArticleMemento articleMemento = STACK.pop(); return articleMemento; } public void addMemento(ArticleMemento articleMemento) { STACK.push(articleMemento); } }
public class Test { public static void main(String[] args) { DraftsBox draftsBox = new DraftsBox(); Editor editor = new Editor("IntelliJ IDEA 中有什么让你相见恨晚的技巧?", "作为一个从事 Java 开发的程序员,每天离不开编辑器的帮助", "https://link.zhihu.com/?target=https%3A//studyidea.cn/articles/2019/06/02/1559465646386.html"); ArticleMemento articleMemento = editor.saveToMemento(); draftsBox.addMemento(articleMemento); System.out.println("editor::: " + editor); System.out.println("=============首次修改============="); editor.setContent("作为一个从事 Java 开发的程序员,每天离不开编辑器的帮助。还记得刚开始学习 Java 编程的时候,使用 Eclipse 作为日常开发工具"); System.out.println("editor::: " + editor); System.out.println("=============首次修改完成============="); articleMemento = editor.saveToMemento(); draftsBox.addMemento(articleMemento); System.out.println("=============保存到草稿箱============="); System.out.println("=============再次修改============="); editor.setContent("作为一个从事 Java 开发的程序员,每天离不开编辑器的帮助。还记得刚开始学习 Java " + "编程的时候,使用 Eclipse 作为日常开发工具。后来工作以后,需要使用 Intellij IDEA,刚开始其实并不想怎么用"); System.out.println("editor::: " + editor); System.out.println("=============再次修改完成============="); System.out.println("=============首次撤销============="); articleMemento = draftsBox.getMemento(); editor.undoFromMemento(articleMemento); System.out.println("editor::: " + editor); System.out.println("=============首次撤销完成============="); System.out.println("=============再次撤销============="); articleMemento = draftsBox.getMemento(); editor.undoFromMemento(articleMemento); System.out.println("editor::: " + editor); System.out.println("=============再次撤销完成============="); } }
在源码中的运用:
Sprig源码中: StateManageableMessageContext
public interface StateManageableMessageContext extends MessageContext { /** * Create a serializable memento, or token representing a snapshot of the internal state of this message context. * @return the messages memento */ public Serializable createMessagesMemento(); /** * Set the state of this context from the memento provided. After this call, the messages in this context will match * what is encapsulated inside the memento. Any previous state will be overridden. * @param messagesMemento the messages memento */ public void restoreMessages(Serializable messagesMemento); /** * Configure the message source used to resolve messages added to this context. May be set at any time to change how * coded messages are resolved. * @param messageSource the message source * @see MessageContext#addMessage(MessageResolver) */ public void setMessageSource(MessageSource messageSource); }
来源:oschina
链接:https://my.oschina.net/u/2954646/blog/3207496