public class Originator { private String state=""; public void changeState(){ this.state="maybe not so good"; } public String getState() { return state; } public void setState(String state) { this.state = state; } public Memento createMemote(){ return new Memento(this.state); } public void restoreMomoto(Memento _memoto){ this.setState(_memoto.getState()); } }
public class Memento { private String state=""; public Memento(String _state) { this.state=_state; } public String getState() { return this.state; } }
public class Caretaker { private Memento memoto; public Memento getMemoto(){ return memoto; } public void setMemoto(Memento memoto){ this.memoto=memoto; } }
public class Client { public static void main(String[] args) { Originator orihinator=new Originator(); //发起人 Caretaker caretaker=new Caretaker(); //备忘录管理者,不能改变内容 orihinator.setState("It's so good"); //设置状态 caretaker.setMemoto(orihinator.createMemote()); //创建备份点 orihinator.changeState(); //改变状态 orihinator.restoreMomoto(caretaker.getMemoto()); //恢复至备份点 } } /* * 这样看来,Memoto备忘录就是一个JavaBean,存储数据。 * 为什么还需要Caretaker? 为了不违背迪米特原则,只和朋友类交流,备份类不是朋友,系统需求只是在某个点创建备份 * 所以备忘录管理类就出来了,看起来又是一个JavaBean,在备忘录之上又包装了一层,麻烦,但是这样结构清晰了许多 * 发起人不需要和备份类交流 * * 例子 : 网站 -> 浏览器 -> cookie -> 网站... * 用户发送一个请求给服务器,服务器会创建一个相对应的session对象,发送数据至浏览器并设置cookie,在一段时间里 * 用户可以访问服务器,服务器可以根据sessionID来判断是哪个session对象 */
public class BeanUtils { //把bean的所有属性及数值放入到Hashmap中 public static HashMap<String,Object> backupProp(Object bean){ HashMap<String,Object> result = new HashMap<String,Object>(); 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; } //把HashMap的值返回到bean中 public static void restoreProp(Object bean,HashMap<String,Object> 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(); } } }
public class Caretaker { //容纳备忘录的容器 private HashMap<String,Memento> memMap = new HashMap<String,Memento>(); public Memento getMemento(String idx) { return memMap.get(idx); } public void setMemento(String idx,Memento memento) { this.memMap.put(idx, memento); } }
public class Originator { private String state1=""; //状态1 private String state2=""; //状态2 private String state3=""; //状态3 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; } /** * 创建备份,将该实例的所有属性通过反射得到HashMap集合 * 然后通过Memento的构造方法注入startMap中 * @return */ public Memento createMemote(){ return new Memento(BeanUtils.backupProp(this)); } /** * 因为权限的关系,外部不可能传进来一个Memento对象,这里就将就的使用了一个HashMap集合 * 通过反射,将该实例的所有属性值替换成hashMap中的值 * @param map */ public void restoreMomoto(HashMap<String,Object> map){ BeanUtils.restoreProp(this, map); } /** * 内置类,别人不可能访问 * 实现一个空接口是为了与外部关联,在实际的开发中一个业务接口,一个空接口用于其它子模块,通过反射就可以为所欲为了 * @author suibian */ private class Memento implements IMemento{ private HashMap<String,Object> startMap; public Memento(HashMap<String,Object> _startMap) { this.startMap=_startMap; } public HashMap<String, Object> getStartMap() { return startMap; } public void setStartMap(HashMap<String, Object> startMap) { this.startMap = startMap; } } /*测试使用 */ @Override public String toString() { return "state1="+state1+"\t state2="+state2+"\t state3="+state3; } }
public class Caretaker { private HashMap<String,IMemento> map=new HashMap<String,IMemento>(); public IMemento getMemoto(String idx){ return map.get(idx); } /** * 多个备份 * @param idx 时间锉 * @param memoto 备份接口 */ public void setMemoto(String idx,IMemento memoto){ this.map.put(idx, memoto); } }
public class Client { @SuppressWarnings("unchecked") public static void main(String[] args) { Originator ori1 = new Originator(); Caretaker caretaker = new Caretaker(); ori1.setState1("备份1状态1"); ori1.setState2("备份1状态2"); ori1.setState3("备份1状态3"); caretaker.setMemoto("第一个", ori1.createMemote()); Originator ori2 = new Originator(); ori2.setState1("备份2状态1"); ori2.setState2("备份2状态2"); ori2.setState3("备份2状态3"); caretaker.setMemoto("第二个", ori2.createMemote()); System.out.println(ori1.toString()); System.out.println(ori2.toString()); System.out.println("----------------------备份完毕----------------------------"); ori1.setState1("备份1状态1改变了"); System.out.println("改变后的:"+ori1.toString()); System.out.println("-----------------------开始恢复-----------------------------"); IMemento memento = caretaker.getMemoto("第一个"); //从备份管理获取备份实例 //得到是Memento中的属性startMap再转化成能注参的map对象 HashMap<String,Object> data=(HashMap<String, Object>) BeanUtils.backupProp(memento).get("startMap"); for(Entry<String, Object> e:data.entrySet()){ System.out.println("这是存起来的备份数据:"+e.getKey()+"\t"+e.getValue()); } //将备份实例中的数据data通过反射注入到ori1中去 ori1.restoreMomoto(data); System.out.println("------------------恢复完后的数据-------------------------"); System.out.println(ori1.toString()); System.out.println(ori2.toString()); } } /*错误地方 *通过 BeanUtils.backupProp(memento)获取的是对象Memento类的所有属性值 *而Originator恢复需要的是一个hashMap通过反射注参,一个属性名对应一个值,而上面获取的hashMap是一个属性名,一个hashMap对象 *因为权限只能由Originator来恢复,所以修改了restoreMomoto()方法,不传Memento,而传一个HashMap对象 */
我是菜鸟,我在路上。