备忘录模式

2018-04-30  本文已影响0人  joychic

定义

在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可以将该对象恢复到原先保存的状态。

使用场景

结构

简单实现

一个简单的便签功能Demo

/**
 * @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());
    }
}

小结

备忘录模式的关键在于设计备忘录类和负责人类,需要防止原发器以外的其它对象访问备忘录

备忘录对象通常封装了原发器的部分或所有状态信息,而且这些信息不能被其他对象访问;也就是说不能在备忘录对象之外保存原发器的状态

原发器可以调用备忘录的所以信息,允许原发器访问先前状态所有数据

负责人只负责备忘录的保存并将备忘录对象传递给其他对象

其他对象只需要从负责人处取出备忘录对象并将原发器对象的状态恢复,而无需关心备忘录的保存细节

思考

上一篇下一篇

猜你喜欢

热点阅读