2010-02-22 50 views
4

我有一個自定義的INIFile類,我寫了包含字段下的字段的讀/寫INI文件。我有幾個我想使用這個類來序列化的類,但是我對這樣做最好的方式感到困惑。我考慮過兩種可能的方法。手動對象序列化在Java中

方法1:定義像ObjectPersistent接口執行兩種方法如下所示:

public interface ObjectPersistent 
{ 
    public void save(INIFile ini); 
    public void load(INIFile ini); 
} 

每個類將隨後負責使用INIFILE類輸出所有屬性出到文件中。

方法2:公開的類需要串行化經由getter/setter方法的所有屬性,以便保存可以在一個集中的地方進行處理,如下所示:

public void savePlayer(Player p) 
{ 
    INIFile i = new INIFile(p.getName() + ".ini"); 
    i.put("general", "name", p.getName()); 
    i.put("stats", "str", p.getSTR()); 

    // and so on 
} 

方法1的最好的部分是,不是所有的屬性需要暴露,所以封裝牢固。方法1的壞處在於節省技術上並不是玩家會「做」的東西。它還通過傳入方法的ini對象將我與平面文件聯繫起來,因此稍後切換到關係數據庫將是一個巨大的痛苦。

方法2最好的部分是所有的I/O都集中到一個位置,而實際的保存過程對您來說是完全隱藏的。它可以保存到平面文件或數據庫。方法2的壞處在於我必須完全公開類內部成員,以便集中式序列化器可以從類中獲取所有數據。

我想盡可能保持簡單。我更喜歡在不使用框架的情況下手動執行此操作。我也絕對不想使用Java中提供的內置序列化。有什麼我在這裏失蹤?任何建議什麼樣的模式最適合這個,我將不勝感激。謝謝。

+1

爲什麼你不想使用內置的序列化? – Bozho 2010-02-22 06:40:02

+0

我希望文件易於閱讀,因此可以在任何文本編輯器中進行更改。 – suinswofi 2010-02-22 07:07:23

+0

爲什麼你不想使用庫/框架? – Thilo 2010-02-22 07:57:11

回答

4

由於您不希望(出於某種原因)使用Java序列化,因此可以使用XML序列化。最簡單的方法是通過XStream

XStream是一個簡單的庫,用於將對象序列化爲XML並返回。

如果你確定你不想使用任何序列化框架,你當然可以使用反射。要點有:

  • getClass().getDeclaredFields()收益類的所有領域 - 公共和私人
  • field.setAccessible(true) - 使通過反射訪問的專用(或保護)字段
  • Modifier.isTransient(field.getModifiers())告訴你的字段是否已經標有transient關鍵字 - 即不符合序列化條件。例如,可以用點符號表示嵌套對象結構 - team.coach.name

所有的序列化庫都使用反射(或introspection)來實現他們的目標。

+0

就我個人而言,我覺得如果你沒有長的數據結構,INI文件提供了一種更清晰和容易查看的方式來表示標題中鍵值對中的數據。我更喜歡使用我的INIFile類,而不是原始帖子中提到的框架。 – suinswofi 2010-02-22 07:08:51

+0

@suinswofi查看更新 – Bozho 2010-02-22 07:22:47

+0

我想我更傾向於序列化的模式。我可以看到反射變得非常混亂,試圖檢查類型併爲我的INIFile中的任何原始類型調用正確的put()。 我想知道像XStream這樣的框架如何執行它們的功能。我沒有看到一個特別乾淨的做法。無論哪種方式,似乎你打破了一些規則,不管這是單一職責規則還是封裝,或者任何其他令人費解的OOP指南。 – suinswofi 2010-02-22 07:34:28

0

這是訪問者模式的工作。

1

我會選擇方法1。

它可能不是最面向對象的方式,但在我的經驗,這是更簡單,更容易出錯,更容易維護比方法2 如果您conserned關於自己的序列提供多個實現,可以使用接口來保存和加載方法。

public interface ObjectSerializer 
{ 
    public void writeInt(String key, int value); 
    ... 
} 

public interface ObjectPersistent 
{ 
    public void save(ObjectSerializer serializer); 
    public void load(ObjectDeserializer deserializer); 
} 

可以改善這些ObjectSerializer /解串器接口有足夠的方法和參數,以涵蓋平面文件和數據庫的情況。