概述
备忘录模式是一种行为型模式,该模式用于保存对象当前状态,并且在之后可以再次恢复到此状态.
备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问,目的是为了保护好被保存的这些对象状态的完整性以及内部实现不向外暴露.
备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式.
定义
在不破坏封闭的前提下,捕获一个兑现的内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态.
使用场景
- 需要保存一个对象在某一个时刻的状态或部分状态
- 如果用一个接口来让其他对象得到这个状态,将会暴露对象的实现细节并破会对象的封装性,一个对象不希望外部直接访问其内部状态,通过中间对象可以间接访问其内部状态
UML 类图
该类图中涉及到的角色
Originator
(发起人) : 负责创建一个备忘录Memento
,可以记录,恢复自身状态.同时Originator
还可以根据需要决定Memento
存储自身的哪些状态.Memento
(备忘录) : 负责存储Originator
对象的内部状态,并可以防止Originator
以外的其他对象对其进行访问.Caretaker
(管理者):负责备忘录Memento
,不能对Memento
的内容进行访问或者操作,只能够将备忘录传递给其他对象。
实例
接下来,我们通过一个简单的记事本应用来看一下备忘录模式的使用,在记事本中,需要有 保存,撤销,重做 的功能,而这些功能的典型应用就是使用备忘录模式.
- 首先定义
Originator
,就是我们记事本的EditText
内容编辑
public class NoteEditText extends EditText {
//....
//创建备忘录对象,即存储编辑器的指定数据
public Memoto createMemoto(){
Memoto memoto = new Memoto();
memoto.text = getText().toString();
memoto.cursor = getSelectionStart();
return memoto;
}
public void restore(Memoto memoto){
setText(memoto.text);
setSelection(memoto.cursor);
}
}
- 创建
Caretaker
,备忘录管理者
public class NoteCaretaker {
//最大存储数量
private static final int MAX = 30;
//存储30条记录
List<Memoto> mMemotos = new ArrayList<>(MAX);
int mIndex = 0;
/**
* 保存备忘录到记录列表中
*/
public void saveMemoto(Memoto memoto){
if (mMemotos.size()>MAX){
mMemotos.remove(0);
}
mMemotos.add(memoto);
mIndex = mMemotos.size()-1;
}
/**
* 获取上一个存档信息,相当于撤销功能
*/
public Memoto getPrevMemoto(){
mIndex = mIndex>0?--mIndex:mIndex;
return mMemotos.get(mIndex);
}
/**
* 获取下一个存档信息,相当于重做功能
*/
public Memoto getNextMemoto(){
mIndex = mIndex<mMemotos.size()-1?++mIndex:mIndex;
return mMemotos.get(mIndex);
}
}
Memento
,相当于一个JavaBean
,用于记录我们需要备忘录备忘哪些状态
public class Memoto {
public String text;
public int cursor;
}
- 最后看一下使用
//屏幕中,有三个按钮,分别是保存Note,撤销Note,重做Note,
//在保存了某个Note后,会在列表中添加一条记录
@OnClick({
R.id.undo, R.id.save, R.id.redo
}) public void btn_click(View view) {
switch (view.getId()) {
case R.id.undo:
mText.restore(mNoteCaretaker.getPrevMemoto());
Toast.makeText(NoteActivity.this, "撤销...", Toast.LENGTH_SHORT).show();
break;
case R.id.save:
Memoto memoto = mText.createMemoto();
mNoteCaretaker.saveMemoto(memoto);
mLogAdapter.add(memoto.text);
mText.setText("");
break;
case R.id.redo:
mText.restore(mNoteCaretaker.getNextMemoto());
Toast.makeText(NoteActivity.this, "重做...", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
优缺点
- 备忘录给人提供了一种可以恢复状态的机制,用户能够比较方便的回到某个历史状态.
备忘录实现了信息的封装,使得用户不需要关心状态保存的细节
备忘录模式同时也是十分消耗资源的, 如果类的成员变量比较多,每一次保存和恢复势必会消耗很多内存.