内容简介:在需要中间值的时候此时需要使用备忘录模式最后书写场景类
在需要中间值的时候此时需要使用备忘录模式
类图
代码
public class Boy { // 男孩的状态 private String state = ""; // 认识女孩后状态改变。 public void changeState(){ this.state = "心情不好"; } public String getState(){ return state; } public void setState(String state){ this.state = state; } }
最后书写场景类
public class Client { public static void main(String [] args){ // 声明出主角 Boy boy = new Boy(); // 初始化状态 boy.setState("心情很棒!"); System.out.println(boy.getState()); // 需要记录下当前的状态,backup用来记录当前的状态。 Boy backup = new Boy(); // 保存当前状态 backup.setState(boy.getState()); // 追女孩的时候,状态改变 boy.changeState(); System.out.println(boy.getState()); // 失败,恢复原状 boy.setState(backup.getState()); } }
反思
此时场景类,为高层模块,或非近亲模块的调用者,此时backup变量为多余的。此时破坏了封装。
此时类比平常使用的备忘录方式,新建一个备忘录,然后保存当前的状态。
改进
类图
public class Boy{ // 进行状态的保留 private String state = ""; // 心情改变 public void changeState(){ this.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()); } }
// 备忘录 public 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; } }
最后场景类
public class Client { public static void main(String[] args){ // 声明主角 Boy boy = new Boy(); // 初始化当前状态 boy.setState("心情很棒!"); // 使用备忘录,记录当前状态 Memento men = boy.createMemento(); // 状态改变 boy.changeState(); // 失败,恢复原状,通过备忘录的方式恢复原状 boy.restoreMemento(mem); } }
继续更改
对于迪米特法则来说,只和朋友类通信,备忘录对象不是朋友类,那么可以创建备份点,需要恢复的时候,直接恢复当前的状态即可。
// 备忘录管理者 public class Caretaker{ // 备忘录对象 private Memento memento; public Memento getMemento(){ return memento; } public void setMemento(Memento memento){ this.memento = memento; } }
上方是一个最简单javaBean 即,可重用的组件
改进后的场景类如下
public class Client { public static void main(String[] args){ // 声明主角 Boy boy = new Boy(); // 声明出备忘录管理者 Caretaker caretaker = new Caretaker(); // 初始化当前状态 boy.setState("good!"); // 记录当前状态 caretaker.setMemento(boy.createMemento()); // 状态改变 boy.changeState(); // 恢复原先状态 boy.restoreMemento(caretaker.getMemento()); } }
应用
需要保存恢复数据的当前状态的场景
提供一个可回滚的操作,例如ctrl + z
数据库的事物,使用备忘录模式,因为当一个事物执行失败的时候,进行回滚。
生命周期,使用的时候需要,不使用的时候直接删除
性能,不要重复的建立,恢复,否则会影响系统性能。
和原型模式结合使用
原型模式,通过原型,快速的复制出多个对象。即通过复制的方式,产生对象的一个内部状态。
将备忘录管理和当前状态融合在一起的类。
public interface Cloneable { protected Originator clone(); }
public class Originator implements Cloneable { // 内部状态 private String state = ""; // 获取一个state public String getState(){ return state; } // 设置一个state public void setState(String state){ this.state = 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(); } } }
在设置备忘录管理员
public class Caretaker { // 发起人对象 private Originator originator; public Originator getOriginator(){ return originator; } public void setOriginator(Originator originator){ this.originator = originator; } }
上方为一个java bean
最后发起了自主备份和恢复
此时依旧可以继续更改,进行合并
public class Originator implements Cloneable { private Originator backup; // 内部状态 private String state = ""; public String getState(){ return state; } public void setState(String state){ this.state = 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; } }
使用了一个类,同时管理当前状态,以及当前的备忘录
最后场景类
public class Client { public static void main(String[] args){ // 定义发起人 Originator originator = new Originator(); // 建立初始状态 originator.setState("初始状态"); // 建立备份 originator.createMemento(); // 修改状态 originator.setState("修改状态"); // 恢复原有状态 originator.restoreMemento(); } }
多状态的备忘录模式
// 发起人角色 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 Memento createMemento(){ Beanutils.restoreProp(this,_mementi.getStateMap()); } }
BeanUtils工具类
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 beaninfo = introspector.getBeaninfo(bean.getClass()); // 获得属性描述,使用getPropertyDescriptors方法获取当前的属性的描述符 PropertyDescriptor[] descriptors = beaninfo.getPropertyDescriptors(); // 利用循环取出描述 for(PropertyDescriptor des:descriptors){ // 属性名称 String fieldName = des.getName(); // 设置一个读取属性的方法,其中getReadMethod返回一个类型为Method类型的方法。 Method getter = des.getReadMethod(); // 读取属性值, invoke 调用包装在在内的bean对象的new Object参数的方法,返回值为getter。上方获得了一个读该属性的方法,然后调用该方法invoke方法,将bean对象包装进入,调用参数为空的数组获取返回的对象。 Object fieldValue = getter.invoke(bean, new Object[]{}); if(!fieldName.equalslgnoreCase("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 = intospector.getBeaninfo(bean.getClass()); // 获得属性描述 PropertyDescriptor[] descriptors = beaninfo.getPropertyDescriptors(); // 遍历所有的属性 for(PropertyDescriptor des:descriptors){ // 属性名称 String fieldName = des.getName(); // 如果有这个属性 if(propMap.containsKey(fieldName)){ // 写属性的方法 Method setter = des.getWriteMethod(); seeter.invoke(bean, new Object[]{propMap.get(fieldName)}); } } }catch(Exception e){ // 异常处理 e.printStackTrace(); } } }
备忘录角色
public class Memento { // 接受HashMap作为状态 private HashMap<String, Object> stateMap; // 接受一个对象,建立备份 public Memento(HashMap<String, Object> map){ this.stateMap = map; } public HashMap<String, Object> getStateMap(){ return stateMap; } public void setStateMap(HashMap<String, Object>stateMap){ this.stateMap = stateMap; } }
编写场景类
public class Client{ public static void main(String[] args){ // 定义发起人 Originator ori = new Originator(); // 定义管理员 Caretaker caretaker = new Caretaker(); // 初始化 ori.setState1("1"); ori.setState2("2"); ori.setState3("3"); // 创建备忘录 caretaker.setMemento(ori.createMemento()); // 修改状态值 ori.setState1("4"); ori.setState2("5"); ori.setState3("6"); // 恢复备忘录 ori.restoreMemento(caretaker.getMemento()); } }
多备份的备忘录
定义备忘录管理员
public class Caretaker { // 容纳备忘录的容器 private HashMap<String ,Memento> memMap = new HashMap<String, Memento>(); public Memento getMemento(String idx){ return menMap.get(idx); } public void setMemento(String idx, Memento memento){ this.memMap.put(idx, memento); } }
定义场景类
public class Client{ public static void main(String[] args){ // 定义发起人 Originator originator = new Originator(); // 定义备忘录管理员 Caretaker caretaker = new Caretaker(); // 创建备忘录 caretaker.setMemento("001", originator.createMemento()); caretaker.setMemento("002", originator.createMemento()); // 恢复指定标记的备忘录 originator.restoreMemento(caretaker.getMemento("001")); } }
ps: 会有内存溢出问题
对封装更改权限
可以使用内部类的方式进行权限的限制
// 定义发起人 public class Originator { // 内部状态 private String state = ""; public String getState(){ return state; } public void setState(String state){ this.state = state; } // 创建备忘录 public 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; } } }
在上方中内置的Memento是private访问权限只有自己能访问。
若要产生关联关系,通过接口
public interface IMemento{ }
// 备忘录管理者 public class Caretaker { // 备忘录对象 // 定义一个接口 private IMemento memento; public IMemento getMemento(){ return memento; } public void setMemento(IMemento memento){ this.memento = memento; } }
总结
使用备忘录模式,直接定义一个类,进行备忘即可。
用途,用于恢复某个节点。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。