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

简介:

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

现实案列:回退  Ctrl+Z

角色:

        发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
        备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
        管理角色:对备忘录进行管理,保存和提供备忘录。

UML:

java设计模式--备忘录模式_第1张图片

实例:

package com.sl.demo.memento;
/**
 * 备忘录
 * @author pengkun
 *
 */
public class Memento {
	//备份状态
	private String state="";

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

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
	
	
}
package com.sl.demo.memento;
/**
 * 管理角色
 * @author pengkun
 *
 */
public class Caretaker {
	//持有备忘录
	private Memento memento;
	//提供 get set

	public Memento getMemento() {
		return memento;
	}

	public void setMemento(Memento memento) {
		this.memento = memento;
	}
	
}
package com.sl.demo.memento;


/**
 * 发起人
 * @author pengkun
 *
 */
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(this.state);
	}
	/**
	 * 恢复
	 */
	public void restoreMemento(Memento memento) {
		this.setState(memento.getState());
	}
	
}

测试:

	@Test
	public void test() {
		//发起人
		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());
		
	}

结果

初始状态:状态1
修改后:状态2
恢复后:状态1

有可能有人会想到,这只是备份一个,那我要备份多个呢?

多备份

package com.sl.demo.memento;

import java.util.Map;

/**
 * 备忘录
 * @author pengkun
 *
 */
public class Memento2 {
	//备份状态
	private Map stateMap;

	public Memento2(Map stateMap) {
		super();
		this.stateMap = stateMap;
	}

	public Map getStateMap() {
		return stateMap;
	}

	public void setStateMap(Map stateMap) {
		this.stateMap = stateMap;
	}

	
	
	
	
}
package com.sl.demo.memento;

import java.util.HashMap;
import java.util.Map;

/**
 * 管理角色
 * @author pengkun
 *
 */
public class Caretaker2 {
	//持有备忘录
	private Map mementoMap=new HashMap<>();
	//提供 get set

	public Memento2 getMemento(String key) {
		return mementoMap.get(key);
	}

	public void setMementoMap(String key,Memento2 memento2) {
		mementoMap.put(key, memento2);
	}

	
}
package com.sl.demo.memento;


/**
 * 发起人
 * @author pengkun
 *
 */
public class Originator2 {
	//状态
	private String state1="";
	private String state2="";
	private String state3="";

	
	public String getState1() {
		return state1;
	}
	public String getState2() {
		return state2;
	}
	public String getState3() {
		return state3;
	}
	public void setState1(String state1) {
		this.state1 = state1;
	}
	public void setState2(String state2) {
		this.state2 = state2;
	}
	public void setState3(String state3) {
		this.state3 = state3;
	}
	/**
	 * 备份
	 */
	public Memento2 createMemento() {
		return new Memento2(BeanUtils.backupProp(this));

	}
	/**
	 * 恢复
	 */
	public void restoreMemento(Memento2 memento) {
		BeanUtils.restoreProp(this, memento.getStateMap());
	}
	@Override
	public String toString() {
		return "Originator2 [state1=" + state1 + ", state2=" + state2 + ", state3=" + state3 + "]";
	}
	
	
}

帮助类:

package com.sl.demo.memento;

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

public class BeanUtils {
	/**
	 * 用反射得到类的字段名称和值放入map的key  value
	 * @param bean
	 * @return
	 */
	public static Map backupProp(Object bean){
		Map result = new HashMap();
		try{
			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
			for(PropertyDescriptor des: descriptors){
				String fieldName = des.getName();//字段名称
				Method getter = des.getReadMethod();//get方法
				System.out.println("fieldName:"+fieldName+"getter:"+getter);
				Object fieldValue = getter.invoke(bean, new Object[]{});
				if(!fieldName.equalsIgnoreCase("class")){
					result.put(fieldName, fieldValue);
				}
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	/**
	 * 用反射得到类的字段名称,并且把map相对应的key的value赋值到该对象字段
	 * @param bean
	 * @param propMap
	 */
	public static void restoreProp(Object bean, Map 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();
		}
	}

}

测试:

@Test
public void test2() {
	//发起人
	Originator2 originator=new Originator2();
	originator.setState1("初始1");
	originator.setState2("初始2");
	originator.setState3("初始3");
	System.out.println("初始状态:"+originator);
	//修改前我要备份
	Caretaker2 caretaker=new Caretaker2();
	caretaker.setMementoMap("1",originator.createMemento());
	originator.setState1("修改1");
	originator.setState2("修改2");
	originator.setState3("修改3");
	System.out.println("修改后:"+originator);
	//发现修改错了,我要恢复
	originator.restoreMemento(caretaker.getMemento("1"));
	System.out.println("恢复后:"+originator);
	
}

结果:
初始状态:Originator2 [state1=初始1, state2=初始2, state3=初始3]
fieldName:classgetter:public final native java.lang.Class java.lang.Object.getClass()
fieldName:state1getter:public java.lang.String com.sl.demo.memento.Originator2.getState1()
fieldName:state2getter:public java.lang.String com.sl.demo.memento.Originator2.getState2()
fieldName:state3getter:public java.lang.String com.sl.demo.memento.Originator2.getState3()
修改后:Originator2 [state1=修改1, state2=修改2, state3=修改3]
恢复后:Originator2 [state1=初始1, state2=初始2, state3=初始3]

 

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