备忘录模式

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管理角色:对备忘录进行管理,保存和提供备忘录。
 */

你可能感兴趣的:(exception,bean,String,object,Class,文本编辑)