备忘录模式

纵然是瞬间 提交于 2020-03-21 01:19:57

3 月,跳不动了?>>>

又称为快照模式或令牌模式, 是指在不破坏封装的前提下, 捕获一个对象的内部状态, 
并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
    特征: 后悔药;属于行为型模式

使用场景
    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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!