备忘录模式(Memento)

249 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

备忘录模式

保存一个对象的某个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
这就好比我们拍照的照片,保留某一时刻的状态,所以这种设计模式也叫快照模式

结构

发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

备忘录(Memento)角色:负责存储发起人的内部状态,并防止发起人以外的对象访问该状态,在需要的时候提供这些内部状态给发起人。

管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

image.png

演示

1、发起人

public class Originator {
    private String state;
    private String name;
    public Originator(String name, String state) {
        this.state = state;
        this.name = name;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getState() {
        return this.state;
    }
    public String getName() {
        return this.name;
    }
    public Memento createMemento() {
        return new Memento(this);
    }
    public void restoreMemento(Memento memento) {
        this.setState(memento.getState());
    }
}

2、备忘录

public class Memento {
    private String name;
    private String state;
    public Memento(Originator originator) {
        this.state = originator.getState();
        this.name = originator.getName();
    }
    public String getState() {
        return this.state;
    }
    public String getName() {
        return this.name;
    }
}

3、管理者

public class Caretaker {
    private Map<String, Memento> map = new HashMap<>();
    public void saveMemento(Memento memento) {
        map.put(memento.getName(), memento);
    }
    public Memento getMemento(String name) {
        return map.get(name);
    }
}

4、客户端

public class Client {
    public static void main(String[] args) {
        Originator originator = new Originator("张三", "休息中");
        Caretaker careTaker = new Caretaker();
        System.out.println("开始状态:" + originator.getState());
        careTaker.saveMemento(originator.createMemento());
        originator.setState("开始工作");
        System.out.println("状态更新:" + originator.getState());
        careTaker.saveMemento(originator.createMemento());
        originator.setState("太阳太毒,中暑了。。。");
        System.out.println("状态更新:" + originator.getState());
        originator.restoreMemento(careTaker.getMemento(originator.getName()));
        System.out.println("出现问题,状态恢复到:" + originator.getState());
        // 开始状态:休息中
        // 状态更新:开始工作
        // 状态更新:太阳太毒,中暑了。。。
        // 出现问题,状态恢复到:开始工作
    }
}

总结

优点

1、实现了内部封装,除了这个状态的发起人能访问这个状态,其他对象不能访问

2、简化了各个对象的职责,发起人不需要管理内部信息的各个备份,信息都保存在备忘录中备份,并由管理员进行管理,符合单一职责原则。

缺点

如果发起人内部信息太多或者保存频繁,会比较占内存资源