备忘录模式
备忘录模式(Memento Pattern)又称之为快照模式(Snapshop Pattern)或者令牌模式(Token Pattern),是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,这样我们就可以在需要的时候将该对象恢复到原先保存的状态了,备忘录模式属于行为型模式。
备忘录模式可以为我们提供一种“后悔药”的机制,它通过存储系统中各个历史状态的快照,使得可以在任一时刻将系统回滚到历史状态。
示例:我们通过一个常见的富文本编辑器来举例说明...
package cn.liangyy.memento;
import java.util.Date;
/** * 文章信息类 */public class ArticleText { //文章标题 private String title; //文章内容 private String content; //文章创建时间 private Date createTime;
public ArticleText(String title, String content, Date createTime) { this.title = title; this.content = content; this.createTime = createTime; }
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 Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
/** * 保存快照 * @return */ public ArticleMemento saveToMemento(){ ArticleMemento articleMemento = new ArticleMemento(this.title,this.content,this.createTime); return articleMemento; }
/** * 还原文章 * @param articleMemento */ public void getArticleFromMemento(ArticleMemento articleMemento){ this.title = articleMemento.getTitle(); this.content = articleMemento.getContent(); this.createTime = articleMemento.getCreateTime(); }}
复制代码
package cn.liangyy.memento;
import java.util.Date;
/** * 存储文章快照类 * 这个类和存储文章信息的类内部属性必须保持一致,否则无法通过快照类进行恢复,即使恢复了也不完整 */public class ArticleMemento { private String title; private String content; private Date createTime;
public ArticleMemento(String title, String content, Date createTime) { this.title = title; this.content = content; this.createTime = createTime; }
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 Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }}
复制代码
package cn.liangyy.memento;
import java.util.ArrayList;import java.util.List;
/** * 管理历史快照信息 */public class ArticleCaretaker { private final List<ArticleMemento> list = new ArrayList<>();
public ArticleMemento getArticle(int index){ return list.get(index); }
public void setArticle(ArticleMemento articleMemento){ list.add(articleMemento); }}
复制代码
package cn.liangyy.memento;
import java.util.Date;
/** * 备忘录模式-测试 */public class TestMemento { public static void main(String[] args) { ArticleCaretaker articleCaretaker = new ArticleCaretaker();
ArticleText articleText = new ArticleText("标题1","内容1",new Date()); ArticleMemento articleMemento = articleText.saveToMemento(); //备份1次 articleCaretaker.setArticle(articleMemento);
articleText = new ArticleText("标题2","内容2",new Date()); System.out.println(String.format("修改后的标题为[%s],内容为[%s]",articleText.getTitle(),articleText.getContent()));
articleText.getArticleFromMemento(articleCaretaker.getArticle(0)); System.out.println(String.format("还原后的标题为[%s],内容为[%s]",articleText.getTitle(),articleText.getContent())); }}
复制代码
上述例子就是一个备忘录模式的实现,其实就是通过两个类来实现备份,并通过中间对象进行存储。
备忘录模式适用场景备忘录模式作为一个程序员应该没有没使用过的,比如 svn、git 等都是提供了历史版本的管理功能,这些就是备忘录模式的体现,还有富文本的编辑之类的都可以使用备忘录模式来进行实现,服务器的快照功能也可以使我们回退到历史状态。备忘录模式一般用于以下场景:
备忘录模式优点简化了发起人的职责,将状态的存储和获取进行了隔离,而且客户端无需关心状态的保存细节。
备忘录模式缺点消耗资源,如果每个快照的内容都非常大,会消耗大量内存。
评论