`

行为型-备忘录模式

 
阅读更多

定义

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

UML



 

1.Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。

2.Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。

3.Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操作。

实例

class Originator {
	private String state = "";
	
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public Memento createMemento(){
		return new Memento(this.state);
	}
	public void restoreMemento(Memento memento){
		this.setState(memento.getState());
	}
}

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;
	}
}
class Caretaker {
	private Memento memento;
	public Memento getMemento(){
		return memento;
	}
	public void setMemento(Memento memento){
		this.memento = memento;
	}
}
public class Client {
	public static void main(String[] args){
		Originator originator = new Originator();
		originator.setState("状态1");
		System.out.println("初始状态:"+originator.getState());
		Caretaker caretaker = new Caretaker();
		caretaker.setMemento(originator.createMemento());
		originator.setState("状态2");
		System.out.println("改变后状态:"+originator.getState());
		originator.restoreMemento(caretaker.getMemento());
		System.out.println("恢复后状态:"+originator.getState());
	}
}

多备份状态实例

class Originator {
	private String state1 = "";
	private String state2 = "";
	private String state3 = "";

	public String getState1() {
		return state1;
	}
	public void setState1(String state1) {
		this.state1 = state1;
	}
	public String getState2() {
		return state2;
	}
	public void setState2(String state2) {
		this.state2 = state2;
	}
	public String getState3() {
		return state3;
	}
	public void setState3(String state3) {
		this.state3 = state3;
	}
	public Memento createMemento(){
		return new Memento(BeanUtils.backupProp(this));
	}
	
	public void restoreMemento(Memento memento){
		BeanUtils.restoreProp(this, memento.getStateMap());
	}
	public String toString(){
		return "state1="+state1+"state2="+state2+"state3="+state3;
	}
}
class Memento {
	private Map<String, Object> stateMap;
	
	public Memento(Map<String, Object> map){
		this.stateMap = map;
	}

	public Map<String, Object> getStateMap() {
		return stateMap;
	}

	public void setStateMap(Map<String, Object> stateMap) {
		this.stateMap = stateMap;
	}
}
class BeanUtils {
	public static Map<String, Object> backupProp(Object bean){
		Map<String, Object> result = new HashMap<String, Object>();
		try{
			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
			for(PropertyDescriptor des: descriptors){
				String fieldName = des.getName();
				Method getter = des.getReadMethod();
				Object fieldValue = getter.invoke(bean, new Object[]{});
				if(!fieldName.equalsIgnoreCase("class")){
					result.put(fieldName, fieldValue);
				}
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	
	public static void restoreProp(Object bean, Map<String, Object> propMap){
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
			for(PropertyDescriptor des: descriptors){
				String fieldName = des.getName();
				if(propMap.containsKey(fieldName)){
					Method setter = des.getWriteMethod();
					setter.invoke(bean, new Object[]{propMap.get(fieldName)});
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
class Caretaker {
	private Map<String, Memento> memMap = new HashMap<String, Memento>();
	public Memento getMemento(String index){
		return memMap.get(index);
	}
	
	public void setMemento(String index, Memento memento){
		this.memMap.put(index, memento);
	}
}
class Client {
	public static void main(String[] args){
		Originator ori = new Originator();
		Caretaker caretaker = new Caretaker();
		ori.setState1("中国");
		ori.setState2("强盛");
		ori.setState3("繁荣");
		System.out.println("===初始化状态===\n"+ori);
		
		caretaker.setMemento("001",ori.createMemento());
		ori.setState1("软件");
		ori.setState2("架构");
		ori.setState3("优秀");
		System.out.println("===修改后状态===\n"+ori);
		
		ori.restoreMemento(caretaker.getMemento("001"));
		System.out.println("===恢复后状态===\n"+ori);
	}
}

 

 

 

优点

1、将被存储的状态放在外面,不要和关键对象混在一起,这可以帮助维护内聚。有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。

2、保持关键对象的数据封装。本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。

3、提供了容易实现的恢复能力。当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

 

缺点

1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。

2、当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。

 

使用场景

如果有需要提供回滚操作的需求,使用备忘录模式非常适合,比如jdbc的事务操作,文本编辑器的Ctrl+Z恢复等。

有一句话在java中可以考虑序列化机制存储系统的状态,后期看看相关资料。

 

以上主要摘自:http://baike.baidu.com/link?url=YyxgNeiUxlt1suM6gXF9faEMoDepBKlyEXCEWiEfVIiWNCSNpMztaMH0K4ZYxEjqmqMqH7CkkGlZAgcrO6Irsa和http://blog.csdn.net/zhengzhb/article/details/7697549

  • 大小: 22 KB
分享到:
评论

相关推荐

    JAVA-设计模式-行为型模式-备忘录模式

    JAVA-设计模式-行为型模式-备忘录模式

    c++设计模式-行为型模式-备忘录模式

    c++设计模式-行为型模式-备忘录模式;qt工程;c++简单源码;备忘录(Memento)模式的定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先...

    设计模式_行为型_备忘录模式.md

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

    C#面向对象设计模式纵横谈(21):(行为型模式) Memento 备忘录模式

    C#面向对象设计模式纵横谈(21):(行为型模式) Memento 备忘录模式

    设计模式_备忘录模式.zip

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

    (行为型模式) Memento 备忘录模式

    C#面向对象设计模式 (行为型模式) Memento 备忘录模式 视频讲座下载

    备忘录模式

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

    设计模式课件大全

    PPT内容包括:内附代码,实例,方便理解。...设计模式14-中介者模式、备忘录模式 设计模式15-观察者模式、状态模式 设计模式16-策略模式、模板方法、访问者 此PPT实例便于理解,对于深入理解OO思想有很大帮助。

    [行为型模式] 备忘录模式的理解

    NULL 博文链接:https://jacky-dai.iteye.com/blog/2309027

    c#设计模式 行为型模式 实验报告+源代码

    c#设计模式 行为型模式 包括8个设计模式的实验报告+源代码。实验报告包括实验类图和个人总结的一些小技巧,源代码...包括:职责链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式

    行为型模式+结构型模式+创建型模式:三大设计模式实例剖析与深入解读

    行为型模式+结构型模式+创建型模式:三大设计模式实例剖析与深入解读 行为型模式 备忘录模式 +结构型模式 创建型模式总结 +创建型模式

    设计模式之行为型模式

    本课程重点介绍了十一种行为型模式:职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式。

    23种设计模式 (创建型,结构型,行为型)

    创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) ... 备忘录模式(Memento Pattern) 21. 策略模式(Strategy Pattern) 22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    C#23种设计模式样例代码和UML图

    行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 中介者模式、 访问者模式、 状态模式、 备忘录模式); 结构型模式(代理模式、桥接模式、适配器模式、外观模式、...

    设计模式——备忘录模式的学习与理解

    备忘录模式属于行为型模式。 通俗的讲,备忘录故名思意就是去记录某些事情,在程序世界中它主要用来记录一个对象的某种状态,更像是“后悔药”,从备忘录对象里获取原来的数据将对象的状态恢复到原先保存的时候。 ...

    设计模式-C++

    创建型模式,共五种:工厂方法模式、抽象工厂模式、...行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

    23种设计模式 -设计模式图解.7z

    23种设计模式的特点定义、优缺点、使用场景,源码中...行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

    设计模式之11个行为型模式

    行为型简介职责链模式(ChainofResponsibility)命令模式(Command)解释器模式(Interpreter)迭代器模式(Iterator)中介者模式(Mediator)备忘录模式(Memento)观察者模式(Observer)状态模式(State)策略模式(Strategy)模板...

Global site tag (gtag.js) - Google Analytics