19.备忘录模式_备忘录模式

19.备忘录模式_对象状态_02

 

 19.备忘录模式_封装_03

 

 19.备忘录模式_堆栈_04

/**
 * @author wuyimin
 * @create 2021-07-29 11:16
 * @description 原发器角色
 */

public class Chessman {
    //棋子的姓名 x,y坐标
    private String chessName;
    private int x;
    private int y;
    public void show(){
        System.out.println("棋子:"+chessName+"-> 坐标为<"+x+","+y+">");
    }
    //保存当前状态
    public ChessMemo save(){
        return new ChessMemo(chessName,x,y);
    }
    //恢复当前状态
    public void restore(ChessMemo memo){
        this.chessName=memo.getChessName();
        this.x=memo.getX();
        this.y=memo.getY();
    }

    public Chessman(String chessName, int x, int y) {
        this.chessName = chessName;
        this.x = x;
        this.y = y;
    }

    public String getChessName() {
        return chessName;
    }

    public void setChessName(String chessName) {
        this.chessName = chessName;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
/**
 * @author wuyimin
 * @create 2021-07-29 11:21
 * @description 对应备忘录角色
 */

public class ChessMemo {
    //棋子的姓名 x,y坐标
    private String chessName;
    private int x;
    private int y;

    public ChessMemo(String chessName, int x, int y) {
        this.chessName = chessName;
        this.x = x;
        this.y = y;
    }

    public String getChessName() {
        return chessName;
    }

    public void setChessName(String chessName) {
        this.chessName = chessName;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
/**
 * @author wuyimin
 * @create 2021-07-29 11:23
 * @description 负责人角色,负责管理备忘录
 */
public class MementoCaretaker {
    private ArrayList<ChessMemo> list =new ArrayList<ChessMemo>();
    public ChessMemo find(int i){
        return list.get(i);
    }
    public void add(ChessMemo memo){
        list.add(memo);
    }
    public int getCount(){
        return list.size();
    }
}

客户端

public class Client {

    public static void main(String[] args) {
        Chessman chessman = new Chessman("白棋", 1, 1);
        play(chessman);
        chessman.setX(3);
        play(chessman);
        undo(chessman);
        undo(chessman);
        redo(chessman);
        redo(chessman);
    }
    private static int index=-1;
    private static MementoCaretaker mc=new MementoCaretaker();
    //下棋同时输出保存
    public static void play(Chessman chessman){
        ChessMemo save = chessman.save();
        mc.add(save);
        index++;
        chessman.show();
    }
    //悔棋,撤销到上次的步骤
    public static void undo(Chessman chessman){
        System.out.println("---悔棋---");
        if(index<=0){
            System.out.println("悔棋失败");
        }else{
            index--;
            ChessMemo chessMemo = mc.find(index);
            chessman.restore(chessMemo);
            chessman.show();
        }
    }
    //撤销悔棋
    public static void  redo(Chessman chessman){
        System.out.println("--撤销悔棋--");
        if(index>=mc.getCount()-1){
            System.out.println("撤销悔棋失败");
        }else{
            index++;
            ChessMemo chessMemo = mc.find(index);
            chessman.restore(chessMemo);
            chessman.show();
        }
    }
}

备忘录模式的主要优点如下:

它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

备忘录模式的主要缺点如下:

资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。