zoukankan      html  css  js  c++  java
  • 备忘录模式

    备忘录模式

    在对一个对象进行操作时,希望这个操作时可回退的。那么就要保存每一步操作时前一步对象的状态。

    这个时候可以用备忘录模式。

    组成部分

    • 需要记录状态的类
    • 保存对象当前状态和历史状态的类--备忘录类
    • 管理备忘录类的类----提供对备忘录中的对象进行增删改查的方法

    1.需要记录状态的类

     1 @Data
     2 public class BasePo {
     3     private String id;
     4 }
     5 
     6 @Data
     7 @EqualsAndHashCode(callSuper=false)
     8 public class Student extends BasePo{
     9     private String name;
    10     private int age;
    11     private String grade;
    12 }

    2.备忘录类--(保存历史状态时为了减少存储所需空间将对象序列化成了json)

     1 public class Memento<T extends BasePo> {
     2     private T currentState;
     3 
     4     private LinkedList<String> stateJson;
     5 
     6     public T getCurrentState() {
     7         return currentState;
     8     }
     9 
    10     @SuppressWarnings("unchecked")
    11     public void setCurrentState(Object currentState) {
    12         this.currentState = (T) currentState;
    13     }
    14 
    15     public LinkedList<String> getStateJson() {
    16         return stateJson;
    17     }
    18 
    19     public void setStateJson(LinkedList<String> stateJson) {
    20         this.stateJson = stateJson;
    21     }
    22 
    23     @Override
    24     public String toString(){
    25         Field[] fields = currentState.getClass().getDeclaredFields();
    26         StringBuilder builder = new StringBuilder();
    27         for (Field field : fields) {
    28             field.setAccessible(true);
    29             String firstLetter = field.getName().substring(0,1).toUpperCase();
    30             String getMethodName = "get"+firstLetter+field.getName().substring(1);
    31             try {
    32                 Method getMethod = currentState.getClass().getMethod(getMethodName, new Class[] {}); 
    33                 builder.append(" 字段[");
    34                 builder.append(field.getName());
    35                 builder.append("] has value   ");
    36                 builder.append(getMethod.invoke(currentState, new Object[] {})); 
    37             } catch (Exception e) {
    38                  
    39             }
    40             
    41         }
    42         return builder.toString();
    43     }
    44 }

    备忘录类的管理类

    public class MementoManage<T extends BasePo> {
        private HashMap<String, Memento<T>> map = new HashMap<String, Memento<T>>();
        
        public Class<?> getTClass(T t) {
            return t.getClass();
        }
        
        public void add(T entity) throws IllegalAccessException, InvocationTargetException, InstantiationException{
            if (map.containsKey(entity.getId())) {
                update(entity);
            }else {
                Memento<T> memento = new Memento<T>();
                Object t = this.getTClass(entity).newInstance();
                BeanUtils.copyProperties(t, entity);
                memento.setCurrentState(t);
                memento.setStateJson(new LinkedList<String>());
                map.put(entity.getId(), memento);
                System.out.println(memento.toString());
            }
        }
        
        public void update(T entity) throws IllegalAccessException, InvocationTargetException, InstantiationException{
            Memento<T> memento = map.get(entity.getId());
            String json = new Gson().toJson(memento.getCurrentState());
            memento.getStateJson().addLast(json);
            Object t = this.getTClass(entity).newInstance();
            BeanUtils.copyProperties(t, entity);
            memento.setCurrentState(t);
            System.out.println(memento.toString());
        }
        
        public void cancel(T entity){
            Memento<T> memento = map.get(entity.getId());
            if (memento.getStateJson().size()==0) {
                System.out.println("沒有可回退的操作");
                System.out.println(memento.toString());
            }else {
                String json = memento.getStateJson().getLast().toString();
                memento.setCurrentState(new Gson().fromJson(json, Student.class));
                memento.getStateJson().removeLast();
                System.out.println(memento.toString());
            }
        }
        
        public void delete(T entity){
            if (map.containsKey(entity.getId())) {
                map.remove(entity.getId());
            }
        }
    }

    测试类

     1 public static void main(String[] args) throws IllegalAccessException,
     2             InvocationTargetException, InstantiationException {
     3         Student student = new Student();
     4         student.setId(UUID.randomUUID().toString());
     5         student.setAge(19);
     6         student.setName("小红");
     7         student.setGrade("大一");
     8         MementoManage<Student> manage = new MementoManage<Student>();
     9 
    10         manage.add(student);
    11 
    12         student.setAge(22);
    13         manage.update(student);
    14 
    15         manage.cancel(student);
    16 
    17         student.setGrade("初三");
    18         manage.update(student);
    19 
    20         manage.cancel(student);
    21         manage.delete(student);
    22         
    23     }

    测试结果

    字段[name] has value   小红 字段[age] has value   19 字段[grade] has value   大一
    字段[name] has value   小红 字段[age] has value   22 字段[grade] has value   大一
    字段[name] has value   小红 字段[age] has value   19 字段[grade] has value   大一
    字段[name] has value   小红 字段[age] has value   22 字段[grade] has value   初三
    字段[name] has value   小红 字段[age] has value   19 字段[grade] has value   大一
  • 相关阅读:
    【CUDA开发】CUDA面内存拷贝用法总结
    【CUDA开发】CUDA编程接口(一)------一十八般武器
    【CUDA开发】CUDA编程接口(一)------一十八般武器
    【计算机视觉】OPENCV对于有alpha通道的透明背景图片的读取和图片叠加
    【计算机视觉】OPENCV对于有alpha通道的透明背景图片的读取和图片叠加
    【CUDA开发】论CUDA和LAV解码器是否真的实用
    【CUDA开发】论CUDA和LAV解码器是否真的实用
    【VS开发】网络SOCKET编程INADDR_ANY选项
    【VS开发】网络SOCKET编程INADDR_ANY选项
    【FFMPEG】I,P,B帧和PTS,DTS时间戳的关系
  • 原文地址:https://www.cnblogs.com/xushy/p/9360866.html
Copyright © 2011-2022 走看看