zoukankan      html  css  js  c++  java
  • 【设计模式

    1、模式简介

    备忘录模式的定义:

      备忘录模式保存一个对象的某个状态,以便在适当的时候恢复对象,用作“后悔药”,即取消上次操作或返回到以前的某个版本。

    备忘录模式的应用实例:

    • Windows系统中的Ctrl+Z;
    • 浏览器等软件中的后退按钮功能;
    • 数据库的事务管理及回滚功能;
    • 游戏存档。

    备忘录模式的优点:

    • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态;
    • 实现了信息的封装,使得用户不需要关心状态的保存细节。

    备忘录模式的缺点:

      消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

    使用备忘录模式的注意事项:

      在使用备忘录模式的时候,为了节约内存,一般会将原型模式和备忘录模式结合起来使用。

    2、案例

      本案例模拟数据库中的回滚功能。我们将创建一个类来管理对User用户表的操作。具体代码如下:

      备忘录管理类UserCaretaker中的代码如下:

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 备忘录管理类,其中存储所有曾经操作后的数据,单例
     */
    public class UserCaretaker {
        private static UserCaretaker instance; // 单例对象
    
        // 存储所有用户备忘录的集合,key是回滚点名称,value是备忘录对象
        private Map<String, List<HashMap<String, String>>> mementoes;
    
        private UserCaretaker() {
            this.mementoes = new HashMap<>();
        }
    
        // 单例方法
        public static UserCaretaker getInstance() {
            if (instance == null) {
                synchronized (UserCaretaker.class) {
                    if (instance == null) {
                        instance = new UserCaretaker();
                    }
                }
            }
            return instance;
        }
    
        // 添加备忘录
        public void saveMemento(String name, List<HashMap<String, String>> memento) {
            if (!mementoes.containsKey(name)) {
                mementoes.put(name, memento);
            }
        }
    
        // 取出某个备忘录
        public List<HashMap<String, String>> rollbackMemento(String name) {
            if (mementoes.containsKey(name)) {
                return mementoes.get(name);
            }
            return null;
        }
    }

      测试类Test中的代码:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    public class Test {
        public static void main(String[] args) {
            // 创建备忘录集合类
            UserCaretaker caretaker = UserCaretaker.getInstance();
            // 创建用户表
            List<HashMap<String, String>> table1 = new ArrayList<>();
    
            // 向表中添加数据
            table1.add(makeMap("Jack", "20", "Beijing"));
            table1.add(makeMap("Rose", "16", "Shanghai"));
            table1.add(makeMap("Tom", "22", "Nanjing"));
            table1.add(makeMap("David", "10", "Qingdao"));
            // 存储为备忘录
            caretaker.saveMemento("data_added", table1);
            // 打印表中的数据
            System.out.println("--------------初始化数据表---------------");
            selectAllFromTable(table1);
    
            // 修改表中的数据
            List<HashMap<String, String>> table2 = copyList(table1);
            updateData(table2, "Rose", "88", "America");
            // 存储为备忘录
            caretaker.saveMemento("rose_updated", table2);
            // 打印表中的数据
            System.out.println("--------------修改表中数据---------------");
            selectAllFromTable(table2);
    
            // 删除表中的数据
            List<HashMap<String, String>> table3 = copyList(table2);
            deleteData(table3, "Tom");
            // 存储为备忘录
            caretaker.saveMemento("tom_deleted", table3);
            // 打印表中的数据
            System.out.println("--------------删除表中数据---------------");
            selectAllFromTable(table3);
    
            // 回滚到data_added节点
            List<HashMap<String, String>> t = caretaker.rollbackMemento("data_added");
            // 存储为备忘录
            caretaker.saveMemento("rollback_add", t);
            // 打印表中的数据
            System.out.println("--------------回滚到data_added节点---------------");
            selectAllFromTable(t);
        }
    
        // 根据提供的数据生成一条数据
        private static HashMap<String, String> makeMap(String name, String age, String address) {
            HashMap<String, String> map = new HashMap<>();
            map.put("name", name);
            map.put("age", age);
            map.put("address", address);
            return map;
        }
    
        // 更新一条数据
        private static void updateData(List<HashMap<String, String>> table, String name, String age, String address) {
            for (HashMap<String, String> map : table) {
                if (map.get("name").equals(name)) {
                    map.put("age", age);
                    map.put("address", address);
                }
            }
        }
    
        // 删除一条数据
        private static void deleteData(List<HashMap<String, String>> table, String name) {
            for (HashMap<String, String> map : table) {
                if (map.get("name").equals(name)) {
                    table.remove(map);
                }
            }
        }
    
        // SELECT * FROM tb_user
        public static void selectAllFromTable(List<HashMap<String, String>> table) {
            System.out.println("name		age	address");
            for (HashMap<String, String> user : table) {
                System.out.println(user.get("name") + "		" + user.get("age") + "	" + user.get("address"));
            }
            System.out.println();
        }
    
        // 复制一个List(List不能用“=”赋值,只能复制)
        public static List<HashMap<String, String>> copyList(List<HashMap<String, String>> table) {
            List<HashMap<String, String>> list = new ArrayList<>();
            for (HashMap<String, String> map : table) {
                HashMap<String, String> m = new HashMap<>();
                m.put("name", map.get("name"));
                m.put("age", map.get("age"));
                m.put("address", map.get("address"));
                list.add(m);
            }
            return list;
        }
    }

      运行结果如下图所示:

      最后贴出备忘录模式的GitHub代码地址:【GitHub - Memento】

  • 相关阅读:
    常见网络设备工作原理
    Linux逻辑卷的创建
    关于华为模拟器eNSP-防火墙USG6000V怎么重装镜像
    一人之下(名言吧)
    Struts2学习笔记——Struts2搭建和第一个小程序
    eclipse部署Tomcat9
    通过反射访问类的私有方法(无参)
    Java学习笔记之——IO
    Java学习笔记之——线程的生命周期、线程同步
    Java学习笔记之——多线程
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6211191.html
Copyright © 2011-2022 走看看