4

我经常发现自己在为一个类放置序列化代码的地方感到困惑,并且想知道其他人对此主题的想法是什么。

沼泽标准序列化是不费吹灰之力的。只是装饰有问题的班级。

我的问题更多是针对通过各种协议或不同格式序列化的类,并且需要对过程进行一些思考/优化,而不仅仅是盲目地序列化修饰的属性。

我经常觉得让所有代码在自己的类中使用一种格式会更干净。它还允许您通过添加新类来添加更多格式。例如。

class MyClass
{
}

Class JSONWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class BinaryWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class DataBaseSerialiser 
{
    public void Save(MyClass o);
    public MyClass Load();
}

//etc

然而,这通常意味着 MyClass 必须向外界公开更多的内部结构,以便其他类有效地序列化。这感觉是错误的,并且违背了封装。有办法解决它。例如,在 C++ 中,您可以让序列化程序成为朋友,或者在 C# 中,您可以将某些成员公开为显式接口,但仍然感觉不太好。

当然,另一种选择是让 MyClass 知道如何将自己序列化为各种格式:

class MyClass
{
    public void LoadFromJSON(Stream stream);
    public void LoadFromBinary(Stream stream);

    public void SaveToJSON(Stream stream);
    public void SaveToBinary(Stream stream);
    //etc
}

这感觉更加封装和正确,但它将格式与对象结合在一起。如果某些外部类由于 MyClass 不知道的某些上下文而知道如何更有效地序列化怎么办?(也许一大堆 MyClass 对象正在引用同一个内部对象,因此外部序列化程序可以通过只序列化一次来优化)。此外,如果您想要一种新格式,则必须在所有对象中添加支持,而不仅仅是编写一个新类。

有什么想法吗?我个人根据项目的确切需求使用了这两种方法,但我只是想知道是否有人有强烈的理由支持或反对特定方法?

4

2 回答 2

2

最灵活的模式是保持对象轻量级,并为特定类型的序列化使用单独的类。

想象一下如果您需要添加另外 3 种类型的数据序列化的情况。你的类很快就会因为他们不关心的代码而变得臃肿。“对象不应该知道它们是如何被消耗的”

于 2011-11-11T10:47:49.180 回答
2

我想这实际上取决于将使用序列化的上下文以及使用它的系统的限制。例如,由于 Silverlight 反射限制,需要公开一些类属性才能使序列化程序工作。另一个,WCF 序列化程序要求您了解可能的运行时类型 ad-hoc。

除了您指出的之外,将序列化逻辑放入类中违反了 SRP。为什么一个班级需要知道如何将自己“翻译”成另一种格式?

在不同的情况下需要不同的解决方案,但我大多看到单独的序列化程序类在做这项工作。当然它需要暴露类内部的某些部分,但在某些情况下,无论如何你都必须这样做。

于 2011-11-11T10:53:55.327 回答