前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >行为型设计模式:备忘录模式

行为型设计模式:备忘录模式

作者头像
jinjunzhu
发布2020-08-20 15:40:56
3130
发布2020-08-20 15:40:56
举报
文章被收录于专栏:个人开发

在我们平时的开发工作中,很多场景需要我们备份和恢复,比如数据库binlog日志备份、mvcc多版本并发控制、浏览器的回退、Chrome奔溃后重新打开恢复之前的页面。在GOF《设计模式》定义如下:

Captures and externalizes an object’s internal state so that it can be restored later, all without violating encapsulation.

就是不改变原有封装的情况下,捕获和暴露对象的内部状态,以便之后可以用来恢复。

现在假设有一个场景,DBA每天备份一次binlog,有新的binlog日志请求到来时,增加到binlog上,并且日终的时候,保存当天的binlog,如果某一天数据库需要恢复到之前某一天的状态,拿出备份的binlog进行恢复就行。代码如下:

定义一个binlog类,如下:logBuilder记录日志具体内容,createSnapshot用来创建一个快照,restoreSnapshot用来恢复快照

代码语言:javascript
复制
public class Binlog {

    private StringBuilder logBuilder = new StringBuilder();

    public String getText() {
        return logBuilder.toString();
    }

    public void append(String log) {
        logBuilder.append(log);
    }

    public Snapshot createSnapshot() {
        return new Snapshot(this);
    }

    public void restoreSnapshot(Snapshot snapshot) {
        this.logBuilder = new StringBuilder(snapshot.getBinlog().getText());
    }
}
代码语言:javascript
复制

下面是快照类

代码语言:javascript
复制
public class Snapshot {

    private Binlog binlog;

    public Snapshot(Binlog binlog) {
        this.binlog = binlog;
    }

    public Binlog getBinlog() {
        return this.binlog;
    }
}
代码语言:javascript
复制

SnapshotHolder类用来保存和获取快照

代码语言:javascript
复制
public class SnapshotHolder {

    private Map<String, Snapshot> snapshots = new HashMap<>(100);

    public Snapshot getSnapshot(String date) {
        return snapshots.get(date);
    }

    public void storeSnapshot(String date, Snapshot snapshot) {
        snapshots.put(date, snapshot);
    }
}
代码语言:javascript
复制
下面的应用类是增加新日志和用快照恢复数据,如下:
代码语言:javascript
复制
public class ApplicationMain {

    public static void main(String[] args) {
        Binlog binlog = new Binlog();
        SnapshotHolder snapshotsHolder = new SnapshotHolder();
        String newLog = "insert into t values(1, 12345)";
        binlog.append(newLog);
        //备份
        snapshotsHolder.storeSnapshot(DateUtils.getCurrentDate(), new Snapshot(binlog));
        String newLog1 = "insert into t1 values(1, 12345)";
        binlog.append(newLog1);
        //恢复
        binlog = snapshotsHolder.getSnapshot(DateUtils.getCurrentDate()).getBinlog();

    }
}

注意:上面的记录快照的方式用了全量记录的方式,mysqlsh数据库实际也是使用了这种方式。但是这种方式存储成本很高。适用于增量数据比较多的场景。如果增量数据少,可以用于备份增量的方式,这时恢复到之前的某一个快照时,就用之前的增量快照进行累加。

这时修改SnapshotHolder的getSnapshot方法,如下:

代码语言:javascript
复制
public Snapshot getSnapshot(String date) {
        final Binlog binlog = new Binlog();
        for (String key : snapshots.keySet()){
            if (key.compareTo(date) <= 0){
                binlog.append(snapshots.get(date).getBinlog().getText());
            }
        }
        return new Snapshot(binlog);
    }
代码语言:javascript
复制

上面的代码地址:https://github.com/jinjunzhu/design-pattern.git

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 jinjunzhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档