内容简介:在需要中间值的时候此时需要使用备忘录模式最后书写场景类
在需要中间值的时候此时需要使用备忘录模式
类图
代码
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;
}
}
总结
使用备忘录模式,直接定义一个类,进行备忘即可。
用途,用于恢复某个节点。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。