备忘录模式——回到过去

一、模式介绍

备忘录模式,可以在不破坏封装的前提下,捕获和保存一个对象的状态,方便以后在需要的时候,使该对象回到被保存时的状态。备忘录模式为我们提供了一种“后悔药”机制,它同时要求该对象已保存的状态不能被其它对象访问和修改,它主要有以下几种角色组成:

  • 发起人(Originator),保存自己当前的状态、负责创建一个备忘录、具有回滚自己状态的能力;
  • 备忘录(Memento),用于存储发起人需要被保存的状态,同时需要防止除了发起人之外的人来访问和修改被保存的对象;
  • 备忘录管理员(Caretaker),负责存储和管理备忘录,但是要求无法对备忘录的内容进行访问和操作;

备忘录模式的通用写法如下:

/**
 * 备忘录抽象接口,在管理员处使用此接口,可以防止其它对象访问和修改被保存对象的状态
 */
public interface IMemento {}
@Data
public class Memento implements IMemento {
    private String state;

    public Memento(String state){
        this.state = state;
    }
}
@Data
@Slf4j
public class Originator {
    private String state;

    /**
     * 创建一个当前状态的备忘录
     *
     * @return
     */
    public IMemento createMemento() {
        return new Memento(state);
    }

    /**
     * 恢复最近的状态
     * @param memento
     */
    public void restoreMemento(IMemento memento) {
        state = ((Memento)memento).getState();
    }

    /**
     * 展示当前的状态
     */
    public void showState() {
        log.info("当前的状态为:{}", state);
    }
}
public class CareTaker {
    private IMemento memento;

    public IMemento getMemento(){
        return this.memento;
    }

    public void storeMemento(IMemento memento){
        this.memento = memento;
    }
}
public class Main {
    public static void main(String[] args) {
        Originator jack = new Originator();
        jack.setState("alive");
        jack.showState();

        CareTaker admin = new CareTaker();
        // 管理员储存当前发起人的状态
        admin.storeMemento(jack.createMemento());

        // 发起人状态变更
        jack.setState("dead");
        jack.showState();

        // 发起人从管理员处获取先前的状态
        jack.restoreMemento(admin.getMemento());
        jack.showState();
    }
}

二、使用场景

暂无,可以自行实现游戏存档、文档草稿箱等功能。

三、模式总结

3.1 优点

  • 简化了发起人的职责,只要做创建备忘录和决定什么时候恢复状态即可,无须再关心保存状态的细节;
  • 能提供状态回滚的功能,这是其它模式实现不了的;

3.2 缺点

  • 如果需要保存的状态过多,这些状态都会消耗内存,从而导致占用过多的资源;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容