2013-11-21 41 views
1

我正在爲一個課程項目做遊戲,教授說他希望我們實現某種形式的功能來保存遊戲狀態,並且我應該能夠根據需要插入任何「類型」的保存 - 使用序列化的對象,XML,數據庫等......它被建議有一個主接口,並有幾個實現類,使用各自的方法保存...但我不知道如何實際處理這個。如何定義一個「Savable」接口,允許通過任何所需的方法實現類保存?

其中之一,我很困惑哪些類將實現此接口。它會成爲我所有的東西嗎?或者它會成爲保存數據的工作類別?每個對象是否應該負責保存自己的數據,還是一個主類負責保存所有對象的數據?我應該用抽象類來代替嗎?此外,在我看來,我的每個對象將不得不實施Serializable,以防萬一使用這種方法,即使它不會是...

我不需要代碼的幫助,我需要幫助瞭解這種設置的結構,這將最有效。我需要確保一切都儘可能模塊化,因爲這是一個項目,我必須應用軟件工程的許多原則來製作「出色的軟件」......

+1

您需要存儲所有使程序的當前狀態爲唯一的信息。如果你使用的是MVC架構,那麼這就是Model。 – vandale

+0

@vandale對於我需要保存的內容我不會感到困惑,但是如何實現保存代碼,以便我可以隨時改變我的想法,瞭解我希望保存的介質。 – agent154

+0

你正在尋找的界面是'Externalizable'。 – AJMansfield

回答

0

你應該看看不同的design patterns幫助你實現你的要求。

memento pattern例如提供了保存對象並恢復其先前狀態的能力。如果你稍微修改它,它可能適合你的需求:有一些保存應實現Saveable

public interface Saveable { 
    void save(Memento memento); 
    void restore(Memento memento); 
} 

public interface Memento { 
    void putString(String key, String value); 
    String getString(String key); 
    void putInteger(String key, int value); 
    int getInteger(String key); 
    // ... put/get for other data types 
    Memento getChild(String key, boolean createIfNotExisting); 
} 

所有你的遊戲部分。當調用saverestore時,他們將內部表示寫入/從外部狀態對象Memento讀取。

通過具有Memento不同實現,你可以通過XML文件,對象序列化,甚至關係型數據庫實現存儲(XMLMementoSerializationMementoJPAMemento,...)。在運行時,具體實現由abstract factoryfactory method選擇。

用法樣品:

Memento memento = mementoFactory.create(); 
player.save(memento.createChild("player", true)); 
board.save(memento.createChild("board", true)); 
... 
memento.store(); 

例如,Eclipse framwork uses this pattern保存的UI部件的狀態。 (但它提供的唯一實現是XMLMemento)。

另一個有用的模式是builder pattern。其目的是將複雜對象的構建與其表示分離。通過這樣做,相同的構建過程可以創建不同的表示。英文維基頁面錯過了這種模式的一些重要方面,所以如果它符合您的需求,您應該閱讀book中的原始章節。

的一種助劑的使用範例:

GameStateSaver saver = saverFactory.createSaver(); 
saver.savePlayer(player); 
saver.saveBoard(board); 
... 
saver.store(); 

在這裏,遊戲對象本身不知道/他們是如何被保存,而是在GameStateSaver實現了知識。請注意,這也有一個缺點:對象必須通過公共API提供所有狀態(因此內部私有狀態無法保存,因爲它無法通過保存程序訪問)。

+0

我需要爲每個想要保存的對象類型設置不同的Memento類嗎?在我看來,似乎可用的數據類型必須匹配起始者和管理員之間的工作......所以如果我有一個對象的玩家,我需要一個PlayerMemento,所以它知道如何處理相關特定於玩家的信息,如果我想保存遊戲板的狀態,則類似於「Board」。 – agent154

+0

不,該存儲接口從具體的持久性策略中抽象出來,所以每個數據存儲都會有一個實現。 – isnot2bad

1

你已經在考慮的接口存在:java.io.Externalizable

此接口擴展Serializable允許實施者有超過用於存儲對象的格式控制。

但是,Serializable對你來說可能已經足夠了;只需標記不需要保存的字段transient

+0

雖然'Serializable'對我的項目來說可能'夠用',但這不是教授想要的。他希望能夠以最少的代碼更改來改變存儲介質。 – agent154

+0

@ agent154您可以通過更改將對象序列化到什麼ObjectOutputStream來更改「存儲介質」,而不是通過更改序列化過程的實現。 – AJMansfield

0

我不認爲有你的對象實現一個共同的Savable接口是一個好主意。

有一個概念叫persistence-ignorance,你的域模型對象(遊戲中的實體)不應該知道它們是如何存儲的。

您可以讓存儲庫對象負責從數據庫或文件系統或任何其他位置提取和存儲對象,每種類型的數據存儲可以有不同的存儲庫實現。

這樣你就可以保持域邏輯(遊戲信息和事件)和基礎設施(遊戲狀態保存的技術細節)之間的分離。

相關問題