备忘录模式(Memento Pattern)

什么是备忘录模式?

备忘录模式(Memento Pattern)又叫做快照模式(Snapshot Pattern)或Token模式,是GoF的23种设计模式之一,属于行为模式。

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

涉及角色


1. Originator源发器类(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
2. Memento备忘录类(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
3. Caretaker负责人类(管理者):负责保存好备忘录Memento,不能对Memento的内容进行访问或者操作。可以通过增加容器,设置多个备忘点。

场景

  • 录入大批人员资料。正在录入当前人资料时,发现上一个人录错了,此时需要恢复上一个人的资料,在进行修改。
  • Word文档编辑时,忽然电脑死机或断电,在打开是,可以看到word提示你恢复到以前的文档。
  • 管理系统中,公文撤回功能。发送出去后,想撤回来。
  • 棋类游戏中的,悔棋。
  • 普通软件中的,撤销操作。
  • 数据库软件中,事务管理的回滚操作。
  • PhotoShop软件中的,历史记录。

举例

雇员信息的修改及恢复。

类图

代码

Originator源发器类(发起人):

package com.match.memento;

/**
 * Originator源发器类(发起人)
 * @author Match
 *
 */
public class Emp
{
    private String ename;
    private int age;
    private double salary;

    //进行备忘操作,并返回备忘录对象
    public EmpMemento memento()
    {
        return new EmpMemento(this);
    }
    //进行数据恢复,恢复成制定备忘录对象的值
    public void recovery(EmpMemento mmt)
    {
        this.ename=mmt.getEname();
        this.age=mmt.getAge();
        this.salary=mmt.getSalary();
    }
    public Emp(String ename, int age, double salary)
    {
        super();
        this.ename = ename;
        this.age = age;
        this.salary = salary;
    }

    public String getEname()
    {
        return ename;
    }

    public void setEname(String ename)
    {
        this.ename = ename;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public double getSalary()
    {
        return salary;
    }

    public void setSalary(double salary)
    {
        this.salary = salary;
    }   
}

Memento备忘录类(备忘录):

package com.match.memento;

/**
 * Memento备忘录类(备忘录)
 * @author Match
 *
 */
public class EmpMemento
{
    private String ename;
    private int age;
    private double salary;

    public EmpMemento(Emp e)
    {
        this.ename=e.getEname();
        this.age=e.getAge();
        this.salary= e.getSalary();
    }

    public String getEname()
    {
        return ename;
    }

    public void setEname(String ename)
    {
        this.ename = ename;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public double getSalary()
    {
        return salary;
    }

    public void setSalary(double salary)
    {
        this.salary = salary;
    }   
}

Caretaker负责人类(管理者):

package com.match.memento;

/** 
 * Caretaker负责人类(管理者)
 * 负责管理备忘录对象
 * @author Match
 *
 */
public class CareTaker
{
    private EmpMemento memento;
//  private List<EmpMemento> list = new ArrayList<EmpMemento>();

    public EmpMemento getMemento()
    {
        return memento;
    }

    public void setMemento(EmpMemento memento)
    {
        this.memento = memento;
    }

}

客户端:

package com.match.memento;

public class Client
{

    public static void main(String[] args)
    {
        CareTaker taker = new CareTaker();
        Emp emp = new Emp("Match",18,1000000);
        System.out.println("原雇员信息:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
        System.out.println("***************备忘原雇员信息***************");
        taker.setMemento(emp.memento());//备忘一次
        System.out.println("***************修改原雇员信息***************");
        emp.setEname("Bob");
        emp.setAge(20);
        emp.setSalary(100000);
        System.out.println("修改后的雇员信息:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
        System.out.println("***************恢复为原有雇员信息************");
        emp.recovery(taker.getMemento());
        System.out.println("恢复后的雇员信息:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
    }

}

测试输出:

原雇员信息:Match---18---1000000.0
***************备忘原雇员信息***************
***************修改原雇员信息***************
修改后的雇员信息:Bob---20---100000.0
***************恢复为原有雇员信息************
恢复后的雇员信息:Match---18---1000000.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值