类设计:在域对象或助手类中进行序列化

时间:2009-11-04 03:43:37

标签: c# serialization oop

假设我有一些域对象需要使用自定义二进制格式进行序列化/打包,以便可以通过套接字将其发送到外部进程。我的第一直觉是创建一个接口,代表可以打包成这种二进制格式的任何对象。

public interface IPackable
{
    byte[] Pack();
}

然后我的域对象(例如EntityStateVector等)将各自实现此接口。这类似于默认序列化在.NET和Java中的工作方式。

public class Vector : IPackable
{
  public double X { get; set; }
  public double Y { get; set; }
  public double Z { get; set; }

  // other operators and methods...

  public byte[] Pack
  {
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream);

    writer.Write(X);
    writer.Write(Y);
    writer.Write(Z);

    return stream.ToArray();
}

但是,我越了解设计原则(例如SOLID's Single Responsibility Principle),我就越想创建一个单独的类来打包我的域对象。

我可以看到两者的优点和缺点。你们都觉得怎么样?如果答案是创建一个单独的类来打包域对象,我应该为每个域对象创建一个单独的打包器(例如EntityPackerStatePackerVectorPacker等吗?

由于

2 个答案:

答案 0 :(得分:1)

您是否也考虑了System.Runtime.Serialization命名空间?

创建外部序列化程序的麻烦在于您必须将所有有趣的数据打开到另一个对象。由于对象的大多数状态可能都保存在私有变量中,因此对象的公开属性不一定能提供足够的信息来完全从外部描述它。

坚持使用良好的数据封装,我倾向于隐藏正在存储的对象中打包/序列化的细节。

答案 1 :(得分:1)

.NET框架中内置了几种可用于此目的的序列化形式。示例是SOAP,XML以及二进制文件,它非常适合通过各种流(包括网络流)发送对象。

.NET中的二进制序列化也能够序列化和反序列化私有属性和字段,而XML和SOAP格式化器中的构建则不能。

但是,在使用二进制格式化程序时,必须确保它只与.NET库兼容,而SOAP可以从任何支持SOAP的平台读取。