您的位置:首页 > 其它

备忘录模式

2012-07-03 12:45 106 查看
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;

/**

* 设计模式之备忘录模式

*备忘录模式的优点有:

*当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。

*备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。

*

*备忘录模式的缺点:

*在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。

*

*适用场景

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

*/

class Originator {

private String state1 = "";

private String state2 = "";

private String state3 = "";

private String[] state4=null;



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 String[] getState4() {

return state4;

}

public void setState4(String[] state4) {

this.state4 = state4;

}

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+"state4="+state4.length;

}

}

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);

}

}

public class Client {

public static void main(String[] args){

Originator ori = new Originator();//发起者

String[] str = {"飞机"};

ori.setState1("J10");

ori.setState2("J11");

ori.setState3("J20");

ori.setState4(str);

System.out.println("===初始化状态===\n"+ori);



Caretaker caretaker = new Caretaker();//临时替代者

caretaker.setMemento("001",ori.createMemento());//设置备忘录====>备忘录模式关键



String[] str2 = {"软件","职位"};

ori.setState1("项目组长");//修改发起者属性值

ori.setState2("项目经理");

ori.setState3("技术总监");

ori.setState4(str2);

System.out.println("===修改后状态===\n"+ori);



ori.restoreMemento(caretaker.getMemento("001"));//从备忘录中恢复属性值

System.out.println("===恢复后状态===\n"+ori);

}

}

/*注:

*1发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。

*2备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。

*3管理角色:对备忘录进行管理,保存和提供备忘录。

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: