19-备忘录模式
1.备忘录模式
- 没有使用备忘录模式实现数据的显示、追加和撤销操作,存在的问题:InputText中定义了setText()函数,该函数可能被其他业务误用;快照本身是不能修改的,但是InputText中定义了一些列修改内部状态的函数,违反了封闭原则。
// 服务端代码
public class InputText {
private final StringBuilder text = new StringBuilder();
public String getText() {
return this.text.toString();
}
public void append(String input) {
this.text.append(input);
}
public void setText(String text) {
this.text.replace(0, this.text.length(), text);
}
}
public class SnapshotHolder {
private final Stack<InputText> snapshots = new Stack<>();
public InputText popSnapshot() {
return snapshots.pop();
}
public void pushSnapshot(InputText inputText) {
InputText deepCloneInputText = new InputText();
deepCloneInputText.append(inputText.getText());
snapshots.push(deepCloneInputText);
}
}
public class Main {
public static void main(String[] args) {
InputText inputText = new InputText();
SnapshotHolder snapshotHolder = new SnapshotHolder();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String input = scanner.next();
if (input.equals(":list")) {
System.out.println(inputText.getText());
} else if (input.equals(":undo")) {
InputText snapshot = snapshotHolder.popSnapshot();
inputText.setText(snapshot.getText());
} else {
snapshotHolder.pushSnapshot(inputText);
inputText.append(input);
}
}
}
}
// 客户端代码
InputText inputText = new InputText();
SnapshotHolder snapshotHolder = new SnapshotHolder();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String input = scanner.next();
if (input.equals(":list")) {
System.out.println(inputText.getText());
} else if (input.equals(":undo")) {
InputText snapshot = snapshotHolder.popSnapshot();
inputText.setText(snapshot.getText());
} else {
snapshotHolder.pushSnapshot(inputText);
inputText.append(input);
}
}
- 使用备忘录模式实现数据的显示、追加和撤销操作。备忘录模式将快照定义为单独的类Snapshot,对外不提供修改内部状态的函数。
// 备忘录模式服务端代码
public class Snapshot {
private final String text;
public Snapshot(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
public class InputText {
private final StringBuilder text = new StringBuilder();
public String getText() {
return this.text.toString();
}
public void append(String input) {
this.text.append(input);
}
public Snapshot createSnapshot() {
return new Snapshot(text.toString());
}
public void restoreSnapshot(Snapshot snapshot) {
this.text.replace(0, this.text.length(), snapshot.getText());
}
}
public class SnapshotHolder {
private final Stack<Snapshot> snapshots = new Stack<>();
public Snapshot popSnapshot() {
return snapshots.pop();
}
public void pushSnapshot(Snapshot snapshot) {
snapshots.push(snapshot);
}
}
// 备忘录模式客户端代码
InputText inputText = new InputText();
SnapshotHolder snapshotHolder = new SnapshotHolder();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String input = scanner.next();
if (input.equals(":list")) {
System.out.println(inputText.getText());
} else if (input.equals(":undo")) {
Snapshot snapshot = snapshotHolder.popSnapshot();
inputText.restoreSnapshot(snapshot);
} else {
snapshotHolder.pushSnapshot(inputText.createSnapshot());
inputText.append(input);
}
}
2.备忘录模式总结
- <<设计模式:可复用面向对象软件的基础>>中备忘录模式的定义:在不违反封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复对象为先前的状态。
- 备忘录模式可以优雅的实现数据防丢失、撤销和恢复功能。