18-备忘录模式

19-备忘录模式

1.备忘录模式

  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);
    }
}
  1. 使用备忘录模式实现数据的显示、追加和撤销操作。备忘录模式将快照定义为单独的类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.备忘录模式总结

  1. <<设计模式:可复用面向对象软件的基础>>中备忘录模式的定义:在不违反封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复对象为先前的状态。
  2. 备忘录模式可以优雅的实现数据防丢失、撤销和恢复功能。
posted @ 2022-11-27 08:56  行稳致远方  阅读(23)  评论(0)    收藏  举报