【设计模式二十四之备忘录Memento Pattern模式】备忘录Memento Pattern模式

备忘录模式Memento Pattern

  • 细说备忘录模式
    • 细说备忘录模式
      • 定义
      • UML模型
        • 基于UML的代码
      • 备忘录模式变换
        • 使用clone方式的备忘录
          • 外部对象控制的备忘录存储和恢复
          • 由当前对象自行备份存储和恢复
        • 多状态下的备忘录
        • 多备份的备忘录
        • 使用内置类情况下的备忘录,易于扩展
      • 备忘录模式应用和注意事项
        • 备忘录模式应用场景
        • 备忘录模式注意事项

细说备忘录模式

提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041


细说备忘录模式

备忘录模式其实也可以叫做备份模式,其实最主要的作用就是类似保存某一项事务的前置一种或者多种状态,举个例子,windows的数据备份,备份出来了一个节点,当其备份完毕后,无论后面windows出现什么问题,都可以从备份中进行还原,还原到备份的那个节点。还有一个就是git的使用,git每一次的提交其实都是一种备份,将某个提交节点备份记录下来,然后随时可以还原回去某一个节点下,这就是备份,备忘录

定义

备忘录模式: 在不破坏封装性的前提下,捕获一个对象的内部状态,并且在对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态
通俗的解释就是备忘录模式其实就是数据的一种备份,

UML模型

【设计模式二十四之备忘录Memento Pattern模式】备忘录Memento Pattern模式_第1张图片
备忘录模式中有以下几个角色:
1:Originator 备份的发起者,记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据
2:Memento 负责存储Orgiginator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态
3:Caretaker 对备忘录进行管理,保存和提供备忘录的对象

基于UML的代码

package src.com.zzf.designpattern.mementopattern.uml;

/**
 * 备忘录对象
 * @author zhangfei.zhou
 *
 */
public class Memento {
	private String stateString = "";
	
	public Memento(String _state){
		this.stateString = _state;
	}
	
	public void setState(String state){
		this.stateString = state;
	}
	
	public String getState() {
		return stateString;
	}
}

package src.com.zzf.designpattern.mementopattern.uml;

public class Originator {
	private String state = "Originator";
	
	public String getState(){
		return state;
	}
	
	public void setState(String _state){
		System.out.println("------orgin-----:"+state);
		this.state = _state;
		System.out.println("------new -----:"+_state);
	}
	
	Memento createMemento(){
		return new Memento(state);
	}
	
	//恢复一个备忘录
	public void restoreMemento(Memento _memento){
		this.setState(_memento.getState());
	}
}

package src.com.zzf.designpattern.mementopattern.uml;

public class Caretaker {
	//备忘录对象
	private Memento memento;
	
	public Memento getMemento() {
		return memento;
	}
	
	public void setMemento(Memento memento) {
		this.memento = memento;
	}
}

package src.com.zzf.designpattern.mementopattern.uml;

public class Client {
	public static void main(String[] args) {
		//定义出发起人
		Originator originator = new Originator();
		//定义出备忘录管理员
		Caretaker caretaker = new Caretaker();
		//创建一个备忘录
		caretaker.setMemento(originator.createMemento());
		originator.setState("change state ");
		//恢复一个备忘录
		originator.restoreMemento(caretaker.getMemento());
	}
}

上面其实就是基于uml设计的最简单的代码结构。

备忘录模式变换

使用clone方式的备忘录

外部对象控制的备忘录存储和恢复
package src.com.zzf.designpattern.mementopattern.clone1;

/**
 * 利用cloneable
 * @author zhangfei.zhou
 *
 */
public class Originator implements Cloneable {
	//内部结构
	private String state = "Originator";

	public String getState() {
		return state;
	}

	public void setState(String _state) {
		System.out.println("------orgin-----:"+state);
		this.state = _state;
		System.out.println("------new -----:"+_state);
	}
	//创建一个备忘录
	public Originator createMemento() {
		return this.clone();
	}
	//恢复一个备忘录
	public void restoreMemento(Originator _originator) {
		this.setState(_originator.getState());
	}
	//克隆当前对象
	@Override
	protected Originator clone() {
		try {
			return (Originator) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
}

package src.com.zzf.designpattern.mementopattern.clone1;

public class Caretaker {
	//备忘录对象
	private Originator memento;
	
	public Originator getMemento() {
		return memento;
	}
	
	public void setMemento(Originator memento) {
		this.memento = memento;
	}
}

package src.com.zzf.designpattern.mementopattern.clone1;


public class Client {
	public static void main(String[] args) {
		//定义出发起人
		Originator originator = new Originator();
		//定义出备忘录管理员
		Caretaker caretaker = new Caretaker();
		//创建一个备忘录
		caretaker.setMemento(originator);
		originator.setState("change state ");
		//恢复一个备忘录
		originator.restoreMemento(caretaker.getMemento());
	}
}

由当前对象自行备份存储和恢复
package src.com.zzf.designpattern.mementopattern.clone2;

/**
 * 利用cloneable
 * @author zhangfei.zhou
 *
 */
public class Originator implements Cloneable {
	//内部结构
	private String state = "Originator";
	//内部自我备份对象
	private Originator backup;
	
	public String getState() {
		return state;
	}

	public void setState(String _state) {
		System.out.println("------orgin-----:"+state);
		this.state = _state;
		System.out.println("------new -----:"+_state);
	}
	//创建一个备忘录
	public void createMemento() {
		this.backup =  this.clone();
	}
	//恢复一个备忘录
	public void restoreMemento() {
		this.setState(this.backup.getState());
	}
	//克隆当前对象
	@Override
	protected Originator clone() {
		try {
			return (Originator) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
}

package src.com.zzf.designpattern.mementopattern.clone2;


public class Client {
	public static void main(String[] args) {
		//定义出发起人
		Originator originator = new Originator();
		//创建一个备忘录
		originator.createMemento();
		originator.setState("change state");
		//恢复一个备忘录
		originator.restoreMemento();
		System.out.println(originator.getState());
	}
}

多状态下的备忘录

package src.com.zzf.designpattern.mementopattern.mul;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;

public class BeanUtils {
	// 把bean的所有属性和数值放入到Hashmap中
	public static HashMap backupProp(Object bean) {
		HashMap result = new HashMap();
		try {
			// 获得Bean描述
			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) {
			// 异常处理
		}
		return result;
	}

	public static void restoreProp(Object bean, HashMap propMap) {
		try {
			// 获得Bean描述
			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) {
			// 异常处理
			System.out.println("shit");
			e.printStackTrace();
		}
	}

}

package src.com.zzf.designpattern.mementopattern.mul;

public 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());
	}

	@Override
	public String toString() {
		return "state1=" + state1 + "\nstat2=" + state2 + "\nstate3=" + state3;
	}
}

package src.com.zzf.designpattern.mementopattern.mul;

import java.util.HashMap;

public class Memento {
	private HashMap stateMap;
	
	public Memento(HashMap map){
		this.stateMap = map;
	}
	
	public HashMap getStateMap() {
		return stateMap;
	}
	
	public void setStateMap(HashMap stateMap) {
		this.stateMap = stateMap;
	}
}

package src.com.zzf.designpattern.mementopattern.mul;

public class Caretaker {
	//备忘录对象
	private Memento memento;
	
	public Memento getMemento() {
		return memento;
	}
	
	public void setMemento(Memento memento) {
		this.memento = memento;
	}
}

package src.com.zzf.designpattern.mementopattern.mul;



public class Client {
	public static void main(String[] args) {
			//定义发起人
			Originator ori = new Originator();
			//定义一个备忘录管理员
			Caretaker caretaker = new Caretaker();
			//初始化
			ori.setState1("state1");
			ori.setState2("state2");
			ori.setState3("state3");
			System.out.println("===初始化===\n"+ori);
			//创建一个备忘录
			caretaker.setMemento(ori.createMemento());
			//修改状态值
			ori.setState1("state4");
			ori.setState2("state5");
			ori.setState3("state6");
			System.out.println("\n===修改后==\n"+ori);
			//恢复一个备忘录
			ori.restoreMemento(caretaker.getMemento());
			System.out.println("\n===还原后===\n"+ori);
	}
}

多备份的备忘录

package src.com.zzf.designpattern.mementopattern.mul;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;

public class BeanUtils {
	// 把bean的所有属性和数值放入到Hashmap中
	public static HashMap backupProp(Object bean) {
		HashMap result = new HashMap();
		try {
			// 获得Bean描述
			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) {
			// 异常处理
		}
		return result;
	}

	public static void restoreProp(Object bean, HashMap propMap) {
		try {
			// 获得Bean描述
			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) {
			// 异常处理
			System.out.println("shit");
			e.printStackTrace();
		}
	}

}

package src.com.zzf.designpattern.mementopattern.mul;

import java.util.HashMap;

public class Memento {
	private HashMap stateMap;
	
	public Memento(HashMap map){
		this.stateMap = map;
	}
	
	public HashMap getStateMap() {
		return stateMap;
	}
	
	public void setStateMap(HashMap stateMap) {
		this.stateMap = stateMap;
	}
}

package src.com.zzf.designpattern.mementopattern.mul;

public 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());
	}

	@Override
	public String toString() {
		return "state1=" + state1 + "\nstat2=" + state2 + "\nstate3=" + state3;
	}
}

package src.com.zzf.designpattern.mementopattern.mul2;

import java.util.HashMap;

import src.com.zzf.designpattern.mementopattern.mul.Memento;

public class Caretaker {
	// 容纳备忘录的容器
	private HashMap memMap = new HashMap();

	public Memento restore1Originator1(String idx) {
		return memMap.get(idx);
	}

	public void setMemento(String idx, Memento memento) {
		this.memMap.put(idx, memento);
	}
}

package src.com.zzf.designpattern.mementopattern.mul2;

import src.com.zzf.designpattern.mementopattern.mul.Memento;
import src.com.zzf.designpattern.mementopattern.mul.Originator;

public class Client {
	public static void main(String[] args) {
		//定义发起人
		Originator ori = new Originator();
		//定义一个备忘录管理员
		Caretaker caretaker = new Caretaker();
		//初始化
		ori.setState1("state1");
		ori.setState2("state2");
		ori.setState3("state3");
		System.out.println("===初始化===\n"+ori);
		//创建一个备忘录
		caretaker.setMemento("001",ori.createMemento());
		//修改状态值
		ori.setState1("state4");
		ori.setState2("state5");
		ori.setState3("state6");
		caretaker.setMemento("002",ori.createMemento());
		System.out.println("\n===修改后==\n"+ori);
		//恢复一个备忘录
		//修改状态值
		ori.setState1("state7");
		ori.setState2("state8");
		ori.setState3("state9");
		caretaker.setMemento("003",ori.createMemento());
		System.out.println("\n===修改后==\n"+ori);
		
		Memento restore1Originator1 = caretaker.restore1Originator1("002");
		ori.restoreMemento(restore1Originator1);
		System.out.println("\n===还原后002===\n"+ori);
		
		Memento restore1Originator2 = caretaker.restore1Originator1("001");
		ori.restoreMemento(restore1Originator2);
		System.out.println("\n===还原后001===\n"+ori);
		
		Memento restore1Originator3 = caretaker.restore1Originator1("003");
		ori.restoreMemento(restore1Originator3);
		System.out.println("\n===还原后003===\n"+ori);
	}
}

使用内置类情况下的备忘录,易于扩展

package src.com.zzf.designpattern.mementopattern.me;

/**
 * 创建一个空接口
 * @author zhangfei.zhou
 *
 */
public interface IMemento {
}

package src.com.zzf.designpattern.mementopattern.me;

public class Originator {
	private String state = "Originator";

	public String getState() {
		return state;
	}

	public void setState(String _state) {
		System.out.println("------orgin-----:" + state);
		this.state = _state;
		System.out.println("------new -----:" + _state);
	}

	IMemento createMemento() {
		return new Memento(this.state);
	}

	// 恢复一个备忘录
	public void restoreMemento(IMemento _memento) {
		this.setState(((Memento) _memento).getState());
	}

	private class Memento implements IMemento {
		private String state = "";

		private Memento(String _state) {
			this.state = _state;
		}

		private String getState() {
			return state;
		}

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

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

package src.com.zzf.designpattern.mementopattern.me;

public class Caretaker {
	//备忘录对象
	private IMemento memento;
	
	public IMemento getMemento() {
		return memento;
	}
	
	public void setMemento(IMemento memento) {
		this.memento = memento;
	}
}

package src.com.zzf.designpattern.mementopattern.me;

public class Client {
	public static void main(String[] args) {
			//定义发起人
			Originator ori = new Originator();
			//定义一个备忘录管理员
			Caretaker caretaker = new Caretaker();
			//初始化
			ori.setState("state1");
			System.out.println("===初始化===\n"+ori);
			//创建一个备忘录
			caretaker.setMemento(ori.createMemento());
			//修改状态值
			ori.setState("state4");
			System.out.println("\n===修改后==\n"+ori);
			//恢复一个备忘录
			ori.restoreMemento(caretaker.getMemento());
			System.out.println("\n===还原后===\n"+ori);
	}
}

备忘录模式应用和注意事项

备忘录模式应用场景

1:需要保存和恢复数据的相关场景
2:提供一个可回滚的操作
3:需要监控的相关副本的场景
4:数据库连接备份等等场景

备忘录模式注意事项

1:备忘录的生命周期,备忘录在创建出来就要在最近的代码中进行使用,要主动管理其生命周期,如果不用则立即删除
2:限制备忘录建立对象的数量避免出现资源消耗等等问题

注意本节案例来源于设计模式之禅中的案例




欢迎继续访问,我的博客

你可能感兴趣的:(Java设计模式学习,java设计模式)