备忘录设计模式

备忘录设计模式

一、备忘录设计模式

1、介绍

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


备忘录对象主要用来记录一个对象的某种状态或者某些数据,当要回退时,可以从备忘录对象离获取原来的数据进行恢复操作


备忘录模式属于行为型模式




2、UML

在这里插入图片描述

Orginator:对象(需要保存状态的对象)

Memento:备忘录对象,负责保存Orginator内部状态的

Caretaker:守护者对象,负责保存多个备忘录对象,使用集合管理,提高效率




3、备忘录模式的注意事项和细节

  • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态
  • 实现了信息的封装,使得用户不必关心状态的保存细节
  • 如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存
  • 适用场景:后悔药、游戏存档、windows中的撤回(ctri+z)、浏览器中的后退、数据库的事务管理
  • 为了节约内存,备忘录模式可以和原型模式配合使用




二、案例1

1、介绍

使用备忘录模式,备忘对象Originator的属性state,可通过备忘录对象恢复




2、UML

在这里插入图片描述




3、代码

/**
 * @description: 源
 * @author: dashu
 * @create: 14:09
 */
public class Originator {

    /**
     * 状态
     */
    private String state;

    /**
     * 获取状态
     * @return
     */
    public String getState() {
        return state;
    }

    /**
     * 状态赋值
     * @param state 状态
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * 保存状态到备忘录
     * @return
     */
    public Memento saveStateMemento(){
        return new Memento(state);
    }

    /**
     * 通过备忘录恢复状态
     * @param memento
     */
    public void getSateFromMemento(Memento memento){
        state = memento.getState();
    }

}
/**
 * @description: 备忘录
 * @author: dashu
 * @create: 14:07
 */
public class Memento {

    /**
     * 状态
     */
    private String state;

    public Memento(String state){
        this.state = state;
    }

    public String getState() {
        return state;
    }
}
/**
 * @description: 备忘录管理员
 * @author: dashu
 * @create: 14:13
 */
public class Caretaker {

    /**
     * 备忘录集合
     */
    private List<Memento> mementos = new ArrayList<>();

    /**
     * 备忘录添加
     * @param memento
     */
    public void add(Memento memento){
        mementos.add(memento);
    }

    /**
     * 根据索引索取备忘录
     * @param index 索引值
     * @return
     */
    public Memento get(int index){
        return mementos.get(index);
    }

}
/**
 * @description: 客户端
 * @author: dashu
 * @create: 14:06
 */
public class Client {

    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setState("状态#1 攻击力 100");

        //保存当前状态
        caretaker.add(originator.saveStateMemento());


        originator.setState("状态#2 攻击力 80");

        //保存当前状态
        caretaker.add(originator.saveStateMemento());


        originator.setState("状态#3 攻击力 10");

        //保存当前状态
        caretaker.add(originator.saveStateMemento());

        System.out.println("恢复状态2:");
        originator.getSateFromMemento(caretaker.get(1));
        System.out.println("当前状态:" + originator.getState());
    }

}






三、案例2

1、介绍

通过备忘录模式备忘游戏角色的属性,并通过备忘录对象恢复




2、UML

在这里插入图片描述




3、代码

/**
 * @description: 游戏角色
 * @author: dashu
 * @create: 14:19
 */
public class GameRole {

    /**
     * 攻击力
     */
    private int vit;

    /**
     * 防御力
     */
    private int def;

    public GameRole(int vit, int def) {
        this.vit = vit;
        this.def = def;
    }

    public void display() {
        System.out.println("游戏角色当前的攻击力:" + this.vit + ",防御力:" + this.def);
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }


    public Memento createMemento() {
        return new Memento(vit, def);
    }

    public void recoverGameRoleFromMemento(Memento memento) {
        this.vit = memento.getVit();
        this.def = memento.getDef();
    }

}
/**
 * @description: 备忘录
 * @author: dashu
 * @create: 14:21
 */
public class Memento {

    /**
     * 攻击力
     */
    private int vit;

    /**
     * 防御力
     */
    private int def;

    public Memento(int vit, int def) {
        this.vit = vit;
        this.def = def;
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }
}
import java.util.HashMap;
import java.util.List;

/**
 * @description: 备忘录管理员
 * @author: dashu
 * @create: 14:16
 */
public class Caretaker {

    private Memento memento;

    private List<Memento> mementos;

    private HashMap<String,List<Memento>> rolesMementos;


    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}
/**
 * @description: 客户端
 * @author: dashu
 * @create: 14:26
 */
public class Client {

    public static void main(String[] args) {


        GameRole gameRole = new GameRole(100,100);
        System.out.println("和BOOS大战前状态:");
        gameRole.display();

        System.out.println("保存状态....");
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(gameRole.createMemento());


        System.out.println("和BOOS大战后状态:");
        gameRole.setVit(30);
        gameRole.setDef(30);
        gameRole.display();

        System.out.println("使用备忘录恢复状态....");
        gameRole.recoverGameRoleFromMemento(caretaker.getMemento());
        gameRole.display();

    }

}