简述-备忘录模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ddxxii/article/details/83043433

介绍

备忘录顾名思义就是存储,方便下次使用,达到后悔药的作用。

定义

在不破坏封闭的情况下,捕获对象内部状态,在该对象之外保存这个状态,在需要的时候可以进行恢复。

UML

  • Originator (源头对象): 负责创建一个备忘录,可以记录、恢复自身的内部状态。同时Originator还可以根据需要决定Memnento存储自身的哪些内部状态。
  • Memento(存储状态信息的对象): 备忘录角色,用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。
  • Caretaker(操作的对象):负责存储备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。

使用场景

  • 需要保存对象某一时刻状态
  • 如果用一个接口来让其他对象得到这些状态会暴露实现细节的封装,一个对象不希望外界直接访问其内部状态,通过中间对象(存储状态的对象)可以间接访问其内部状态。

事例

比如咱们在查看一段视频,在退出后再进入,想接着上一次查看的视频点继续看,那么就需存储来支持了。

  1. 建立保存的数据
/**
 * 备忘信息
 */
public class MemoInfo {
    /**
     * 播放点
     */
    private int position;

    public MemoInfo(int position) {
        this.position = position;
    }

    /**
     * 获取
     * @return
     */
    public int getPosition() {
        return position;
    }

    /**
     * 设置
     * @param position
     */
    public void setPosition(int position) {
        this.position = position;
    }
}
  1. 建立使用数据的实体对象
/**
 * 源信息对象
 * 1. 提供创建备忘对象
 * 2. 提供接收备忘对象恢复信息
 */
public interface IOrigin {
    /**
     * 恢复
     * @param memoInfo
     */
    void restorMemo(MemoInfo memoInfo);

    /**
     * 创建
     * @return
     */
    MemoInfo createMemo();
}

/**
 * 源对象实现
 */
public class PlayOrigin implements IOrigin {
    /**
     * 播放点
     */
    private int position;

    public void playInfo() {
        System.out.println("播放点:" + position);
        //播放后前进一个点
        position++;
    }

    /**
     * 接收存储对象恢复当前播放点
     * @param memoInfo
     */
    @Override
    public void restorMemo(MemoInfo memoInfo) {
        this.position = memoInfo.getPosition();
    }

    /**
     * 存储当前播放点返回
     * @return 存储对象
     */
    @Override
    public MemoInfo createMemo() {
        return new MemoInfo(position);
    }
}

  1. 建立存储者
/**
 * 看管者,用于保存存储信息,和获取存储信息
 */
public class Caretaker {
    private MemoInfo memoInfo;

    /**
     * 获取存储信息
     * @return 存储信息
     */
    public MemoInfo getMemoInfo() {
        return memoInfo != null ? memoInfo : new MemoInfo(0);
    }

    /**
     * 保存存储信息
     * @param memoInfo 要存储的信息
     */
    public void saveMemoInfo(MemoInfo memoInfo) {
        this.memoInfo = memoInfo;
    }
}
  1. 测试类:
public static void main(String[] arg) {
        System.out.println("第一次播放");
        PlayOrigin playOrigin = new PlayOrigin();
        playOrigin.playInfo();

        //创建存储信息,并存到看管者那里
        MemoInfo memo = playOrigin.createMemo();
        Caretaker caretaker = new Caretaker();
        caretaker.saveMemoInfo(memo);
        playOrigin.quit();

        System.out.println("再次播放");
        //再次进行播放,从看管者那里拿去信息恢复
        PlayOrigin playOrigin2 = new PlayOrigin();
        playOrigin2.restorMemo(caretaker.getMemoInfo());
        playOrigin2.playInfo();
    }
  1. 输出:
第一次播放
播放点:0
收到存储消息
退出了
再次播放
播放点:1

可以看到输出,再第一次播放后前进了一个点,第二次就接着播放了,那么就达到了从存储拿出来的效果了。

总结:编码上通过状态信息的封装(originator被保存状态的类,Caretaker管理类,Memoto信息类),用户不需要关心状态的保存细节,这是这个模式的一个优点。思想是:存档可再用。像demo这样直接的保存方式,是会耗内存,另一种就是存文件的方式,也是达到这个存储再用的,根据实际情况考虑使用就好。

猜你喜欢

转载自blog.csdn.net/ddxxii/article/details/83043433