在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,之后就可以将该对象恢复到原先保存的状态。
备忘录模式(Memento Pattern)是一种弥补缺陷的模式,能够在失败的操作后读档
public class Boy {
private String state;
/**
* 认识女孩后状态的变化
*/
public void changeState() {
setState("心情可能很不好");
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
/**
* 非备忘录模式
*/
private static void notMemento() {
Boy boy = new Boy();
// 初始化状态
boy.setState("心情很好");
System.out.println("=====男孩现在的状态=====" + boy.getState());
// 记录状态
Boy backup = new Boy();
backup.setState(boy.getState());
// 男孩去追女孩,状态改变
boy.changeState();
System.out.println("=====男孩追女孩之后的状态=====" + boy.getState());
// 追女孩失败,恢复原状
boy.setState(backup.getState());
System.out.println("=====男孩恢复后的状态=====" + boy.getState());
}
/**
* 发起人
*/
public class Man {
private String state;
/**
* 认识女孩后状态的变化
*/
public void changeState() {
setState("心情可能很不好");
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
/**
* 保存一个备份
*
* @return 备忘录
*/
public Memento createMemento() {
return new Memento(this.state);
}
/**
* 恢复一个备份
*/
public void restoreMemento(Memento memento) {
this.state = 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 Caretaker {
/**
* 备忘录角色
*/
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/**
* 加入备忘录管理员
*/
private static void mementoByCaretaker() {
Man man = new Man();
// 创建备忘录管理员
Caretaker caretaker = new Caretaker();
// 初始化状态
man.setState("心情很好");
System.out.println("=====男孩现在的状态=====" + man.getState());
// 记录状态
caretaker.setMemento(man.createMemento());
// 男孩去追女孩,状态改变
man.changeState();
System.out.println("=====男孩追女孩之后的状态=====" + man.getState());
// 追女孩失败,恢复原状
man.restoreMemento(caretaker.getMemento());
System.out.println("=====男孩恢复后的状态=====" + man.getState());
}
/**
* 融合备忘录的发起人角色
*/
public class Originator implements Cloneable {
/**
* 内部状态
*/
private String state;
/**
* 自主备份状态
*/
private Originator backup;
/**
* 认识女孩后状态的变化
*/
public void changeState() {
setState("心情可能很不好");
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
/**
* 保存一个备份
*/
public void createMemento() {
try {
this.backup = this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
/**
* 恢复一个备份
*/
public void restoreMemento() {
this.state = Optional.of(this.backup).orElseGet(Originator::new).state;
}
@Override
protected Originator clone() throws CloneNotSupportedException {
return (Originator) super.clone();
}
}
/**
* 使用克隆完成备忘
*/
private static void mementoByClone() {
// 定义发起人
Originator originator = new Originator();
// 初始化状态
originator.setState("初始化状态");
System.out.println("初始化状态为:" + originator.getState());
// 建立备份
originator.createMemento();
originator.setState("修改后的状态");
System.out.println("修改后的状态:" + originator.getState());
// 恢复原有状态
originator.restoreMemento();
System.out.println("恢复后的状态:" + originator.getState());
}
/**
* 多状态 发起人角色
*/
public class OriginatorMulState {
private String state1;
private String state2;
private String state3;
/**
* 创建一个备忘录
*
* @return 备忘录
*/
public MementoMul createMemento() {
return new MementoMul(BeanUtils.backupProp(this));
}
public void restoreMemento(MementoMul mementoMul) {
BeanUtils.restoreProp(this, mementoMul.getStateMap());
}
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;
}
@Override
public String toString() {
return "OriginatorMulState{" +
"state1='" + state1 + '\'' +
", state2='" + state2 + '\'' +
", state3='" + state3 + '\'' +
'}';
}
}
/**
* 备忘录角色 多状态
*/
public class MementoMul {
private Map<String, Object> stateMap;
public MementoMul(Map<String, Object> stateMap) {
this.stateMap = stateMap;
}
public Map<String, Object> getStateMap() {
return stateMap;
}
public void setStateMap(Map<String, Object> stateMap) {
this.stateMap = stateMap;
}
}
/**
* 多状态 备忘录管理员
*/
public class CaretakerMulState {
/**
* 备忘录角色
*/
private MementoMul memento;
public MementoMul getMemento() {
return memento;
}
public void setMemento(MementoMul memento) {
this.memento = memento;
}
}
/**
* Bean工具类
*/
public class BeanUtils {
/**
* 把bean的所有属性放入到Map中
*
* @param bean 待备忘的对象
* @return 备忘对象的map
*/
public static <T> Map<String, Object> backupProp(T bean) {
Map<String, Object> map = new HashMap<>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor descriptor : descriptors) {
String fieldName = descriptor.getName();
Method getter = descriptor.getReadMethod();
Object fieldValue = getter.invoke(bean);
if (!fieldName.equalsIgnoreCase("class")) {
map.put(fieldName, fieldValue);
}
}
} catch (IntrospectionException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return map;
}
public static <T> void restoreProp(T bean, Map<String, Object> map) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor descriptor : descriptors) {
String fieldName = descriptor.getName();
if (map.containsKey(fieldName)) {
Method setter = descriptor.getWriteMethod();
setter.invoke(bean, map.get(fieldName));
}
}
} catch (IntrospectionException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 多状态 备忘录
*/
private static void mulState() {
OriginatorMulState originatorMulState = new OriginatorMulState();
CaretakerMulState caretaker = new CaretakerMulState();
originatorMulState.setState1("Take");
originatorMulState.setState2("it");
originatorMulState.setState3("boy");
System.out.println("初始化状态:" + originatorMulState);
caretaker.setMemento(originatorMulState.createMemento());
// 修改状态
originatorMulState.setState1("玩");
originatorMulState.setState2("游");
originatorMulState.setState3("戏");
System.out.println("修改后的状态:" + originatorMulState);
// 恢复状态
originatorMulState.restoreMemento(caretaker.getMemento());
System.out.println("恢复后的状态:" + originatorMulState);
}
秦小波《设计模式之禅》