大話設計模式學習筆記(18)——備忘錄模式

源碼git地址 https://github.com/dlovetco/designMode

問題提出

玩遊戲的時候在打boss之前都會保存一下,如果被boss打死了還可以讀檔重新來過。試着用代碼實現這種保存的機制。

代碼寫到現在,相信小夥伴們都應該知道要注意一些什麼事情。
比如:
- 降低類與類之間的耦合性,儘量面向接口編程
- 儘可能的降低類的可見性。客戶端能接觸到的類越少越好(包括類的實現細節),這就要求我們在設計的時候儘可能的考慮封裝性。

備忘錄模式

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到原先保存的狀態。

package memento;

import java.util.HashMap;
import java.util.Map;

public class MementoMode {
    public static void main(String[] args) {
        Status status = new Status(100, 100, 100);
        SaveManager saveManager = new SaveManager();
        saveManager.createSave(status.save());
        System.out.println(status);
        status.attack = 0;
        status.defend = 0;
        status.hp = 0;
        System.out.println(status);
        status.load(saveManager.getSave(1));
        System.out.println(status);
    }
}

/**
 * 狀態
 */
class Status {
    int attack;

    int defend;

    int hp;

    public Status(int attack, int defend, int hp) {
        this.attack = attack;
        this.defend = defend;
        this.hp = hp;
    }

    /**
     * 保存
     */
    public Save save() {
        return new Save(attack, defend, hp);
    }

    /**
     * 載入存檔
     */
    public void load(Save save) {
        this.attack = save.attack;
        this.defend = save.defend;
        this.hp = save.hp;
    }

    @Override
    public String toString() {
        return "Status{" +
                "attack=" + attack +
                ", defend=" + defend +
                ", hp=" + hp +
                '}';
    }
}

class SaveManager {
    Map<Integer, Save> saveMap = new HashMap<>();

    public void createSave(Save save) {
        saveMap.put(saveMap.size() + 1, save);
    }

    public Save getSave(int num) {
        return saveMap.get(num);
    }

}

/**
 * 存檔
 */
class Save {
    int attack;

    int defend;

    int hp;

    public Save(int attack, int defend, int hp) {
        this.attack = attack;
        this.defend = defend;
        this.hp = hp;
    }
}

輸出:
Status{attack=100, defend=100, hp=100}
Status{attack=0, defend=0, hp=0}
Status{attack=100, defend=100, hp=100}

Status是角色的實時狀態,Save是角色在某個瞬間保存下來的狀態然後把這個save對象移交給SaveManager管理。
注意:備忘錄模式其實是使用額外的空間保存目標對象的“快照”。所以如果目標對象過於龐大,那麼在使用備忘錄模式之前 須“三思而後行

plantuml

@startuml
class Save{
}
Save <.. Status
class Status{
save()
load()
}
Save <..* SaveManager
class SaveManager{
Map<Integer, Save> saveMap
createSave()
getSave()
}
@enduml

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章