Java设计模式:备忘录模式

1.备忘录模式

备忘录模式又叫(Memento)是对象的行为模式。

备忘录对象(Memento)对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉,并外部化,存储起来,从而可以在合适的时候把这个对象还原到存储起来的状态。


2.备忘录模式的结构

备忘模式的总体结构:



参与模式的角色:

备忘录角色(Memento)

主要责任:
(1)存储发起人Originator对象的内部状态。
(2)保护对象的内容不被发起人对象以外的任何对象获取。

发起人角色(Originator)

主要责任:创建一个备忘录对象,存储内部状态。

负责人角色(Caretaker)

(1)负责保存备忘录对象。
(2)不检查备忘录对象的内容。


3.备忘录模式的白箱实现。

在结构图可以看见,Memento对发起人提供宽接口,即发起人可以读取备忘录的全部内容,而对负责人提供窄接口,限制负责人对备忘录内容的读取。
如果不考虑这两种接口的区别,对发起人和负责人提供一样的接口,就是白箱实现。白箱实现对备忘录内容的保护靠的是程序员的自律,实现也很简单。

Memento(备忘录)
public class Memento
{
    private String state;

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

    public String getState()
    {
        return this.state;
    }

    public void setState(String state)
    {
        this.state = state;
    }
}


Originator(发起人)
public class Originator
{
	/**
	 * 需要存储的状态,也有不需要存储的状态
	 */
    private String state;  

    //创建备忘录对象
    public Memento createMemento()
    {
        return new Memento(state);
    }

    //从备忘录中恢复状态
    public void restoreMemento(Memento memento)
    {
        this.state = memento.getState();
        System.out.println("restore state = " + this.state);
    }

    public String getState()
    {
        return this.state;
    }

    public void setState(String state)
    {
        this.state = state;
        System.out.println("Current state = " + this.state);
    }
}

Caretaker(负责人)

public class Caretaker
{
    /**
     * 备忘录对象
     */
    private Memento memento;

    public Memento retrieveMemento()
    {
        return this.memento;
    }

    public void saveMemento(Memento memento)
    {
     	this.memento = memento;
    }
}

Client(测试代码)
public class Client
{
    private static Originator o = new Originator();
    private static Caretaker c = new Caretaker();

    public static void main(String[] args)
    {
        o.setState("On");

	    // 存储内部状态
	    c.saveMemento( o.createMemento() );
	
	    // 改变状态
	    o.setState("Off");

	    // 恢复状态
	    o.restoreMemento( c.retrieveMemento() );

    }
}

输出:
Current state = On
Current state = Off
restore state = On

4.更加完善的备忘录模式:黑箱实现

白箱实现发起人和负责人提供相同接口,使得负责人可以访问备忘录全部内容,并不安全。
黑箱实现中:备忘录向发起人提供宽接口,而向负责人提供窄接口。要在Java中实现这种功能,可以将Memento设置成Originator的内部类,对外提供另一个窄接口。

代码实现如下:

MementoIF(备忘录对外提供的窄接口)
//对除发起人以外的对象提供的窄接口
public interface MementoIF
{
}

Originator(发起人)具体备忘录作为其内部类实现


public class Originator
{
    public Originator()
    {
    }

    private String state;



	public MementoIF createMemento()
	{
		return new Memento( this.state );
	}
	
	public void restoreMemento( MementoIF memento)
	{
        Memento aMemento = (Memento) memento;

		this.setState( aMemento.getState() );
	}

    public String getState()
    {
        return this.state;
    }

    public void setState(String state)
    {
        this.state = state;
        System.out.println("state = " + state);
    }
    
    /**
     * 备忘录作为内部类存在
     * 
     */
	
	class Memento implements MementoIF
	{
		private String savedState;
		
		private Memento(String someState)
		{
			savedState = someState;
		}
		
		private void setState(String someState)
		{
			savedState = someState;
		}

		private String getState()
		{
			return savedState;
        }
	}
}

Caretaker

public class Caretaker
{
    /**
     * 备忘录的窄接口
     */
    private MementoIF memento;

    //获取备忘录
    public MementoIF retrieveMemento()
    {
        return this.memento;
    }
    
    
    //存储备忘录对象
    public void saveMemento(MementoIF memento)
    {
     	this.memento = memento;
    }
}

Client(测试代码)

public class Client
{
    private static Originator o = new Originator();
    private static Caretaker c = new Caretaker();

    public static void main(String[] args)
    {
        o.setState("On");

	    // 创建备忘录
	    c.saveMemento( o.createMemento() );
	
	    // 改变状态
	    o.setState("Off");

	    // 恢复状态
	    o.restoreMemento( c.retrieveMemento() );
    }
}


5.备忘录模式的变形

备忘录模式有很多实现方式和变形。
(1)可以让负责人调用备忘录和发起人,进行备份和恢复备份,客户端就不用再协调备忘录和发起人。
(2)演示代码中演示的单状态、单备份的备忘录模式。要实现多状态备份,可以在Memento角色中加人容器来存储状态;要实现多备份备忘录模式,可以在Caretaker中加入容器来存储多个备份。



6.备忘录模式的优缺点

(1)优点:
  • 备忘录把复杂的发起人内部信息对其它对象屏蔽起来,恰当地保持封装的边界。
  • 简化了发起人,不用再管理和保存内部状态的一个个版本。
  • 发起人的状态可以恢复。
(2)缺点:备份占用的资源可能很大。

7.参考资料

(1)http://blog.csdn.net/zhengzhb/article/details/7697549,实现了一个多状态多备份的备忘录模式

(2)《Java与模式》











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值