设计模式之备忘录模式

备忘录模式

概述

备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

这种设计模式无论在生活中还是开发中都是非常常见的,比如不存在的后悔药等,而在开发中比如ctrl+z回退、Photoshop的历史记录等

示例程序

而对于我们开发者比较常见的一个功能在于发布程序版本的,有时候紧急部署一个新的版本却发现不能用,我们可以迅速的回滚到上个版本。在示例程序中我们模拟在发布上线的过程中记录线上配置文件用于紧急回滚

名称说明
ConfigFile配置文件类,此类不属于备忘录模式的核心
ConfigMemento备忘录类,此类管理ConfigFile
ConfigOriginator记录者类,此类拥有生成ConfigMemento的方法
Admin管理员类

代码实现

ConfigFile

@Data
@AllArgsConstructor
public class ConfigFile {
    private String versionNo; // 版本号
    private String content;   // 内容
    private Date dateTime;    // 时间
    private String operator;  // 操作人
}

ConfigMemento

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConfigMemento {
    private ConfigFile configFile;
}

ConfigOriginator

saveMemento保存包网路的时候会创建一个备忘录信息,并返回去,交给管理者处理

getMemento获取到之后并不是直接返回,而是把备忘录的信息交给现在的配置文件this.configFile

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConfigOriginator {
    private ConfigFile configFile;

    public ConfigMemento saveMemento(){
        return new ConfigMemento(configFile);
    }

    public void getMemento(ConfigMemento memento){
        this.configFile = memento.getConfigFile();
    }
}

Admin

public class Admin {
    private int cursorIdx = 0;
    private List<ConfigMemento> mementoList = new ArrayList<>();
    private Map<String, ConfigMemento> mementoMap = new ConcurrentHashMap<>();

    public void append(ConfigMemento memento){
        cursorIdx++;
        mementoList.add(memento);
        mementoMap.put(memento.getConfigFile().getVersionNo(),memento);
    }

    //回退一个版本
    public ConfigMemento undo(){
        if (--cursorIdx <= 0) {
            return mementoList.get(0);
        }
        return mementoList.get(cursorIdx);
    }

    //前进一个版本
    public ConfigMemento redo(){
        if (++cursorIdx > mementoMap.size()){
            return mementoList.get(mementoMap.size() - 1);
        }
        return mementoList.get(cursorIdx);
    }

    //获取某一个版本
    public ConfigMemento get(String versionNo){
        return mementoMap.get(versionNo);
    }
}

Test

@SpringBootTest
class Practice2000ApplicationTests {
    @Test
    void contextLoads() {
        Admin admin = new Admin();
        ConfigOriginator configOriginator = new ConfigOriginator();
        configOriginator.setConfigFile(new ConfigFile("yellowstar0.0.1", "第一次", new Date(), "yellowstar"));
        admin.append(configOriginator.saveMemento());
        configOriginator.setConfigFile(new ConfigFile("yellowstar0.0.2", "第二次", new Date(), "yellowstar"));
        admin.append(configOriginator.saveMemento());
        configOriginator.setConfigFile(new ConfigFile("yellowstar0.0.3", "第三次", new Date(), "yellowstar"));
        admin.append(configOriginator.saveMemento());
        configOriginator.setConfigFile(new ConfigFile("yellowstar0.0.4", "第四次", new Date(), "yellowstar"));
        admin.append(configOriginator.saveMemento());

        configOriginator.getMemento(admin.undo());
        System.out.println("回滚一次" + configOriginator.getConfigFile());

        configOriginator.getMemento(admin.undo());
        System.out.println("再回滚一次" + configOriginator.getConfigFile());

        configOriginator.getMemento(admin.redo());
        System.out.println("前进一次" + configOriginator.getConfigFile());

        configOriginator.getMemento(admin.get("yellowstar0.0.1"));
        System.out.println("到达指定版本" + configOriginator.getConfigFile());
    }
}

//结果
回滚一次ConfigFile(versionNo=yellowstar0.0.4, content=第四次, dateTime=Wed Jun 22 14:48:51 CST 2022, operator=yellowstar)
再回滚一次ConfigFile(versionNo=yellowstar0.0.3, content=第三次, dateTime=Wed Jun 22 14:48:51 CST 2022, operator=yellowstar)
前进一次ConfigFile(versionNo=yellowstar0.0.4, content=第四次, dateTime=Wed Jun 22 14:48:51 CST 2022, operator=yellowstar)
到达指定版本ConfigFile(versionNo=yellowstar0.0.1, content=第一次, dateTime=Wed Jun 22 14:48:51 CST 2022, operator=yellowstar)

总结

备忘录模式是一种对象行为型模式,其主要优点如下

  • 提供一种可以恢复状态的机制,当用户需要时能够比较方便的将数据恢复到某个历史的状态
  • 实现了内部状态的封装,除了创建它的发起人之外,其他对象都不能够访问这些状态信息

缺点也很明显

  • 资源消耗大,如果要保存的内部状态信息过多,将会占用比较大的内存资源
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值