java设计模式---备忘录模式

备忘录模式
定义:
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
涉及角色:
1.Originator(发起人):
负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。
Originator可以根据需要决定Memento存储自己的哪些内部状态。
2.Memento(备忘录):
负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘
录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,
允许它访问返回到先前状态所需要的所有数据。
3.Caretaker(管理者):
负责备忘录Memento,不能对Memento的内容进行访问或者操作。
备忘录模式的优点和缺点
 一、备忘录模式的优点
  1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,
  使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
  2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需
  要的这些状态的版本。
  3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
 二、备忘录模式的缺点:
  1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
  2、当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个
操作是否很昂贵。
  3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。

下面是一个例子:

1.memento:此为备忘录,用来对原发器对象的状态state进行保存:

public class Memento {
 private String state;
 public Memento(String state) {
  this.state = state;
 }
 public String getState() {
  return state;
 }
 public void setState(String state) {
  this.state = state;
 }
}

2.originator:此为原发器,它里面有一个关键状态,用1.中的类可以进行备份,需要的话,可以用这个备份来进行还原。同时此类里面有一个关键的生成备份的creatememento()方法,同时还有一个用于还原的useMemento(Memento m)方法:

public class Originator {
 private String state;
 public String getState() {
  return state;
 }
 public void setState(String state) {
  this.state = state;
 }
 public Memento createMemento() {
  return new Memento(state);
 }
 public void useMemento(Memento m) {
  this.state = m.getState();
 }
 public void showState() {
  System.out.println(state);
 }
}

3.caretaker:此类用来对进行备份的Memento进行存储,然后在需要的时候,调用此类里面的那个memento对象引用:

public class CareTaker {
 private Memento memento;
 public Memento getMemento() {
  return memento;
 }
 public void setMemento(Memento m) {
  this.memento = m;
 }
}

4.测试程序,先设定originator的状态为"正在睡觉中。。。。。。",然后进行备份,而不是直接进行输出状态,接下来再设定其状态为”正在学习中。。。。。。“。输出其状态为”正在学习中。。。。。。“,然后,再把第一个状态还原回来,紧接着输出其状态:

import org.junit.Test;
public class MementoModeTest {
 @Test
 public void testMementoMode() {
  Originator o = new Originator();
  o.setState("正在睡觉中。。。。。。");
  CareTaker ca = new CareTaker();
  ca.setMemento(o.createMemento());
  o.setState("正在学习中。。。。。。");
  o.showState();
  o.useMemento(ca.getMemento());
  o.showState();
 }
}

5.运行结果:

正在学习中。。。。。。

正在睡觉中。。。。。。


6.学习总结:

(1)之所以不在originator里面保存一个memento的引用来保存其状态,是因为这样会产生内聚性,而我们只是生成一个memento对象,用caretaker来对其进行保存。这样的话,其相互依赖关系会宽松一点。

(2)在memento里面,其构造函数之所以要带state参数,是为了后面createMemento()里面返回一个memento时比较方便,如果不带参数的话,此处可能就要变为:

Memento m=new Memento();

m.setState(state);

return m;

可以明显地看到,这样比较麻烦,还不如直接带个参数来得方便。


你可能感兴趣的:(java,设计模式,备忘录模式,java设计模式)