设计模式的艺术 行为型模式之备忘录模式

前言

每个人都会有后悔的时候,可是人生没有后悔药,做过的事情无法再去后悔,软件设计中却是有这么一种后悔机制,叫做备忘录模式,它就是软件中的"后悔药"

什么是备忘录模式  Memento Pattern

在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,这样可以将对象恢复到原先保存的状态,它是一种对象行为型模式,有个别名叫做Token

备忘录模式的优点

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

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

备忘录模式的主要缺点

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

备忘录模式的适用场景

(1)、保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时就能恢复到先前的状态,实现撤销操作

(2)、防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象

备忘录模式的具体实现

目录结构

原发器

package com.company;

//象棋棋子类:原发器
public class Chessman {
    private  String label;
    private int x;
    private int y;

    public Chessman(String label, int x, int y) {
        this.label = label;
        this.x = x;
        this.y = y;
    }
    //保存状态
    public ChessmanMemento save(){
        return  new ChessmanMemento(this.label,this.x,this.y);
    }
    //恢复状态
    public void restore(ChessmanMemento memento){
        this.label=memento.getLabel();
        this.y=memento.getY();
        this.x=memento.getX();
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    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;
    }
}

备忘录

package com.company;

//棋子备忘录
public class ChessmanMemento {
    private  String label;
    private int x;
    private int y;

    public ChessmanMemento(String label, int x, int y) {
        this.label = label;
        this.x = x;
        this.y = y;
    }


    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    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;
    }
}

备忘录管理类

package com.company;

import java.util.ArrayList;

//象棋棋子备忘录管理类:负责人
public class MementoCaretaker {
/*    private ChessmanMemento memento;

    public ChessmanMemento getMemento() {
        return memento;
    }

    public void setMemento(ChessmanMemento memento) {
        this.memento = memento;
    }*/
//定义一个集合来存储多个备忘录
    private ArrayList mementoList=new ArrayList();

    public ChessmanMemento getMemento(int i) {
        return (ChessmanMemento) mementoList.get(i);
    }

    public void setMemento(ChessmanMemento memento) {
        mementoList.add(memento);
    }
}

测试类

package com.company;

public class Client {
    private static int index = -1;  //定义一个索引来记录当前状态所在的位置
    private static MementoCaretaker mc = new MementoCaretaker();

    public static void main(String[] args) {
        Chessman chess = new Chessman("车", 1, 1);
        display(chess);
        chess.setX(4);
        display(chess);
        chess.setX(5);
        display(chess);
        undo(chess, index);
        undo(chess, index);
        redo(chess, index);
        redo(chess, index);
    }

    //撤销悔棋
    private static void redo(Chessman chess, int index) {
        System.out.println("撤销悔棋");
        index++;
        chess.restore(mc.getMemento(index+1));  //恢复到下一个备忘录
        System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "行。");
    }
    //悔棋
    private static void undo(Chessman chess, int index) {
        System.out.println("悔棋");
        index--;
        chess.restore(mc.getMemento(index-1));  //撤销到上个备忘录
        System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "行。");
    }

    private static void display(Chessman chess) {
        mc.setMemento(chess.save());  //保存在备忘录
        index++;
        System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "行。");
    }
}

转载请注明出处,掌声送给社会人

猜你喜欢

转载自blog.csdn.net/SCDN_CP/article/details/83303200