Java實現23種設計模式(十三):備忘錄模式

二十三種設計模式分類

設計模式三大分類.jpg


一、概述

備忘錄(Memento)模式的定義:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,以便以後當需要時能將該對象恢復到原先保存的狀態。該模式又叫快照模式。
主要解決:所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣可以在以後將對象恢復到原先保存的狀態。

優點

備忘錄模式是一種對象行爲型模式,其主要優點如下。

  • 提供了一種可以恢復狀態的機制。當用戶需要時能夠比較方便地將數據恢復到某個歷史的狀態。
  • 實現了內部狀態的封裝。除了創建它的發起人之外,其他對象都不能夠訪問這些狀態信息。
  • 簡化了發起人類。發起人不需要管理和保存其內部狀態的各個備份,所有狀態信息都保存在備忘錄中,並由管理者進行管理,這符合單一職責原則。

缺點

資源消耗大。如果要保存的內部狀態信息過多或者特別頻繁,將會佔用比較大的內存資源。

場景

1、需要保存/恢復數據的相關狀態場景。
2、提供一個可回滾的操作。


二、實現

1. 結構圖

備忘錄模式的主要角色如下。

  • 發起人(Originator)角色:記錄當前時刻的內部狀態信息,提供創建備忘錄和恢復備忘錄數據的功能,實現其他業務功能,它可以訪問備忘錄裏的所有信息。
  • 備忘錄(Memento)角色:負責存儲發起人的內部狀態,在需要的時候提供這些內部狀態給發起人。
  • 管理者(Caretaker)角色:對備忘錄進行管理,提供保存與獲取備忘錄的功能,但其不能對備忘錄的內容進行訪問與修改。

備忘錄模式

PS:UML結構圖可以參考,例子實現並不根據UML圖來完成,靈活實現即可;

2. 實現

  • 對象源狀態
package cn.missbe.model.memento;

import java.io.Serializable;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 * @author lyg  2020/5/6 下午4:16
 * description:
 **/

public class Originator implements Serializable {
    private String state;
    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public void setState(String state){
        this.state = state;
    }

    public String getState(){
        return state;
    }

    public Memento saveStateToMemento(){
        return new Memento(state,info);
    }

    public void getStateFromMemento(Memento memento){
        state = memento.getState();
        info = memento.getInfo();
    }

    @Override
    public String toString() {
        return "Originator{" + "state='" + state + '\'' + ", info='" + info + '\'' + '}';
    }
}
  • 備忘錄對象
package cn.missbe.model.memento;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 *
 * @author lyg  2020/5/6 下午4:16
 * description:
 **/

public class Memento {

    private String state;
    private String info;

    public Memento(String state) {
        this.state = state;
    }

    public Memento(String state, String info) {
        this.state = state;
        this.info = info;
    }

    public String getState() {
        return state;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}
  • 主類,調用測試
package cn.missbe.model.memento;

import java.io.*;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 *
 * @author lyg  2020/5/6 下午4:11
 * description:
 * 備忘錄模式:保存一個對象的某個狀態,以便在適當的時候恢復對象
 * 例如:遊戲存檔、撤銷操作、恢復某個狀態
 **/

public class Main {
    public static void main(String[] args) {
        Originator originator = new Originator();
        originator.setState("state 1");
        originator.setInfo("info 1");
        System.out.println("Originator 1:" + originator);

        ////Method 1:save memory
        Memento memento = originator.saveStateToMemento();
        ///Method 2:save disk
        save2Disk(originator);

        originator.setState("state 2");
        originator.setInfo("info 2");
        System.out.println("Originator 2" + originator);

        ////Method 1:read memory
        originator.getStateFromMemento(memento);
        System.out.println("Originator:" + originator);
        ///Method 2:read disk
        Originator tmp = read2Disk();
        System.out.println("Serializable:" + tmp);
    }

    private static void save2Disk(Originator originator) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("originator.data")))) {
            oos.writeObject(originator);
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static Originator read2Disk() {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("originator.data")))) {
            Object o = ois.readObject();
            return (Originator) o;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章