在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态,这样,之后就能够将该对象恢复到原先保存的状态。android
原发器 Originatorbash
负责建立一个备忘录,能够记录、恢复自身的内部状态。同时 Originator 还能够根据须要决定 Memento 存储自身的哪些内部状态。ide
备忘录 Mementoui
备忘录角色,用于储存 Originator 内部状态,并能够防止 Originator 之外的对象访问 Mementothis
负责人 Caretakerspa
负责存储备忘录,不能对备忘录的内容进行操做和访问,只可以将备忘录传递给其余对象设计
一个简单的便签功能Demorest
/**
* @author jc
* @time 2018/4/30 下午5:59
* @desc 备忘录角色,肯定须要保存的内部状态
*/
public class Memoto {
public String text;
public int cursor;
}
复制代码
/**
* @author jc
* @time 2018/4/30 下午6:07
* @desc NoteEditText充当Originator角色,建立和恢复备忘录
*/
public class NoteEditText extends android.support.v7.widget.AppCompatEditText {
public NoteEditText(Context context) {
this(context, null);
}
public NoteEditText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NoteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 建立备忘录对象 存储编辑的信息
*
* @return
*/
public Memoto createMemoto() {
Memoto memoto = new Memoto();
memoto.text = getText().toString();
memoto.cursor = getSelectionStart();
return memoto;
}
/**
* 从备忘录中恢复数据
*
* @param memoto
*/
public void restore(Memoto memoto) {
setText(memoto.text);
setSelection(memoto.cursor);
}
}
复制代码
/**
* @author jc
* @time 2018/4/30 下午5:56
* @desc 负责管理 Memoto 对象
*/
public class NoteCaretaker {
/**
* 最大存储数量
*/
private static final int MAX = 20;
List<Memoto> mMemotos = new ArrayList<>(MAX);
int mIndex = 0;
/**
* 保存备忘录记录到记录列表中
*
* @param memoto
*/
public void saveMemoto(Memoto memoto) {
if (mMemotos.size() > MAX) {
mMemotos.remove(0);
}
mMemotos.add(memoto);
mIndex = mMemotos.size() - 1;
}
/**
* 获取上一个存档信息
*
* @return
*/
public Memoto getPrevMemoto() {
mIndex = mIndex > 0 ? --mIndex : mIndex;
return mMemotos.get(mIndex);
}
/**
* 获取下一个存档信息,至关于恢复
*
* @return
*/
public Memoto getNextMemoto() {
mIndex = mIndex < mMemotos.size() - 1 ? ++mIndex : mIndex;
return mMemotos.get(mIndex);
}
}
复制代码
public class MementoActivity extends AppCompatActivity implements View.OnClickListener {
NoteEditText noteEditText;
TextView mSavaTv;
TextView mUndoBtn;
TextView mRedoBtn;
NoteCaretaker noteCaretaker = new NoteCaretaker();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memento);
initViews();
}
private void initViews() {
noteEditText = findViewById(R.id.note_et);
mUndoBtn = findViewById(R.id.undo_btn);
mUndoBtn.setOnClickListener(this);
mRedoBtn = findViewById(R.id.redo_btn);
mRedoBtn.setOnClickListener(this);
mSavaTv = findViewById(R.id.save_tv);
mSavaTv.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.undo_btn:
noteEditText.restore(noteCaretaker.getPrevMemoto());
makeToast("撤销 : ");
break;
case R.id.redo_btn:
noteEditText.restore(noteCaretaker.getNextMemoto());
makeToast("恢复 : ");
break;
case R.id.save_tv:
noteCaretaker.saveMemoto(noteEditText.createMemoto());
makeToast("保存 : ");
break;
default:
break;
}
}
private void makeToast(String s) {
Toast.makeText(this, s + " 光标位置 :"
+ noteEditText.getSelectionStart(), Toast.LENGTH_SHORT).show();
Log.v(getClass().getSimpleName(), s + noteEditText.getText());
}
}
复制代码
备忘录模式的关键在于设计备忘录类和负责人类,须要防止原发器之外的其它对象访问备忘录code
备忘录对象一般封装了原发器的部分或全部状态信息,并且这些信息不能被其余对象访问;也就是说不能在备忘录对象以外保存原发器的状态对象
原发器能够调用备忘录的因此信息,容许原发器访问先前状态全部数据
负责人只负责备忘录的保存并将备忘录对象传递给其余对象
其余对象只须要从负责人处取出备忘录对象并将原发器对象的状态恢复,而无需关心备忘录的保存细节