设计模式之备忘录模式

Posted vincentyw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之备忘录模式相关的知识,希望对你有一定的参考价值。

Memento(备忘录模式)

一、备忘录模式简介

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

核心:

  • 1、在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
  • 2、通过一个备忘录类专门存储对象状态
  • 3、客户不与备忘录类耦合,与备忘录管理类耦合

二、备忘录模式优缺点比较

优点:

  • 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态
  • 2、实现了信息的封装,使得用户不需要关心状态的保存细节

缺点:

  • 1、消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存

使用场景:

  • 1、悔棋、撤销
  • 2、数据库事务回滚

注意事项:1、为了符合迪米特原则,还要增加一个管理备忘录的类。 2、为了节约内存,可使用原型模式+备忘录模式。

三、UML类图

技术图片

四、设计实现

  步骤1:创建源发器类

//源发器类
public class Originator {
    private String name ;
    
    //构造器
    public Originator() {}
    
    //保存快照
    public Memento saveState() {
        return new Memento(this.name);
    }
    
    //恢复快照
    public void revertState(Memento men) {
        this.name = men.getName();
        if(this.name == null || "".equals(name)) {
            name = "已还原";
        }
    }
    
    //撤销快照
    public void revokeState(Memento men) {
        this.name = men.getName();
        if(this.name == null || "".equals(name)) {
            name = "已还原";
        }
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Originator [name=" + name + "]";
    }
}

 步骤2:创建备忘录类

public class Memento {
    private String  name ;
    
    public Memento(String n) {
        this.name = n;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Memento [name=" + name + "]";
    }
}

步骤3:创建备忘录管理类

public class CareTaker {
    private int cursor = 0;
    private List<Memento> ms = new ArrayList<>();
    
    //添加快照
    public void  addList(Memento m) {
        if(cursor == 0) {
            ms.add(new Memento(""));
        }
        ms.add(m);
        cursor++;
    }
    
    //恢复上个快照
    public Memento  revertBack() {
//        System.out.println("cursor =" + cursor);
        if(cursor == 0) {
            return ms.get(0);
        }
        return ms.get(--cursor);
    }
    
    //撤销上个快照
    public Memento  revokeNext() {
//        System.out.println("cursor =" + cursor);
        if(cursor<ms.size()-1) {
            return ms.get(++cursor);
        }else {
            return ms.get(ms.size()-1);
        }
    }
    
    @Override
    public String toString() {
        return "CareTaker [ms=" + ms + "]";
    }
}

步骤4:调用者测试

技术图片
public class StateDemo {
    public static void main(String[] args) {
        //初始化源文件
        Originator origin = new Originator();
        //创建管理快照类
        CareTaker ct = new CareTaker();
        //第一次往源文件添加内容
        origin.setName("1");
        //第一次保存快照
        ct.addList(origin.saveState());
        System.out.println("第一次存档,管理类快照显示"+ct.toString());
        //第二次往源文件添加内容
        origin.setName("12");
        //第二次保存快照
        ct.addList(origin.saveState());
        System.out.println("第二次存档,管理类快照显示"+ct.toString());
        //第三次往源文件添加内容
        origin.setName("123");
        //第三次保存快照
        ct.addList(origin.saveState());
        System.out.println("第三次存档,管理类快照显示"+ct.toString());
        System.out.println("-------------------------------------------");
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        origin.revokeState(ct.revokeNext());
        System.out.println("撤销,文档内容为:"+origin.getName());
        origin.revokeState(ct.revokeNext());
        System.out.println("撤销,文档内容为:"+origin.getName());
        origin.revokeState(ct.revokeNext());
        System.out.println("撤销,文档内容为:"+origin.getName());
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        origin.revokeState(ct.revokeNext());
        System.out.println("撤销,文档内容为:"+origin.getName());
        origin.revokeState(ct.revokeNext());
        System.out.println("撤销,文档内容为:"+origin.getName());
        origin.revertState(ct.revertBack());
        System.out.println("恢复,文档内容为:"+origin.getName());
        System.out.println("-------------------------------------------");
        System.out.println("管理类快照显示"+ct.toString());
    }
}
View Code

步骤5:运行程序,观察结果

技术图片

 

以上是关于设计模式之备忘录模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之- 备忘录模式(Memento Pattern)

设计模式之备忘录模式

JAVA SCRIPT设计模式--行为型--设计模式之Memnto备忘录模式(18)

JAVA SCRIPT设计模式--行为型--设计模式之Memnto备忘录模式(18)

行为型设计模式之备忘录模式

行为型设计模式之备忘录模式