2010-02-22 53 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 /解串器接口有足够的方法和参数,以涵盖平面文件和数据库的情况。