行为型设计模式:备忘录模式
Posted 程序员jinjunzhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为型设计模式:备忘录模式相关的知识,希望对你有一定的参考价值。
在我们平时的开发工作中,很多场景需要我们备份和恢复,比如数据库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用来恢复快照
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());
}
}
下面是快照类
public class Snapshot {
private Binlog binlog;
public Snapshot(Binlog binlog) {
this.binlog = binlog;
}
public Binlog getBinlog() {
return this.binlog;
}
}
SnapshotHolder类用来保存和获取快照
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);
}
}
下面的应用类是增加新日志和用快照恢复数据,如下:
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方法,如下:
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);
}
以上是关于行为型设计模式:备忘录模式的主要内容,如果未能解决你的问题,请参考以下文章
JAVA SCRIPT设计模式--行为型--设计模式之Memnto备忘录模式(18)