发送/序列化对象的最佳实践

时间:2011-01-27 01:06:40

标签: java serialization deserialization

问题:开发人员创建自己的序列化格式有多常见?具体来说,我使用java本质上将对象作为带有标记的巨型字符串发送以分隔变量。

我的逻辑:我选择了这个,因为它几乎消除了语言依赖性(忽略了java的修改后的UTF-8),你也没有对象版本问题,如果使用java的序列化,接收端必须具有完全相同的对象的版本,因此在旧版本上运行的客户端将无法接收任何对象数据。代码不是太难看,而且看起来还不错,但我想我的问题是这个实例的最佳实践是什么?这是个人项目。

其他已知的选择:好的,我只是在处理序列化对象以通过网络发送它并遇到了谷歌协议缓冲区。序列化对象的标准化程度如何?我基本上有三种方法可以做到这一点。 (我将在这里讨论java,因为这就是我所做的)1)使用语言的(java)本机序列化类2)使用你自己的方式序列化对象可能使用字符串和标记3)使用Protocol Buffers或一些其他已知格式(JSON,XML等)

从我收集到的内容中,您在序列化时基本上有三个主要目标: 1)速度/效率/尺寸 2)语言独立性 3)版本接受(因为旧版本的代码仍然可以接受新版本的部分,反之亦然)

大多数大型软件项目是否使用协议缓冲区?如果您的客户端是资源少得多的移动设备,它会改变吗?

4 个答案:

答案 0 :(得分:6)

如果您使用标准格式(JSON,XML甚至是原型缓冲区),那么通过集成点扩展应用程序的机会将会大得多。但如果它只是内部的,那么做一切都很容易。就个人而言,我创建了一个专用的持久代理类,它代表给定对象的序列化形式。然后使用writeReplace和readResolve,使用最有意义的方法(用于线上实时传输的Java序列化,用于长期持久性的xml)序列化该对象。随着类的发展,我可以创建持久代理的全新实现,向代理添加版本控制等......视情况而定。我相信Bloch在Effective Java中讨论了这种模式。

至于提出纯粹的从头开始的线程协议,它实际上取决于性能对应用程序的重要程度。与大多数事情一样,您可以越多地利用标准库/协议,您就可以越快地获得新代码。当我看到序列化/等涉及的大量代码时......我通常认为这是一种代码味道,并且非常关注它是否合理。只需我0.02美元。

和PS - 有人发布了关于图表的问题......这实际上是我故意避免标准序列化的一个领域。 Java能够序列化复杂的图形并不是很好 - 如果图形甚至是远程复杂的,你最终会遇到堆栈溢出问题(hah)。在这些情况下,持久代理非常非常重要。

答案 1 :(得分:5)

  

问题:开发人员创建自己的序列化格式有多常见?

假设你的意思是从头开始创建,那么答案就是#34;非常罕见"。

另外,我说它不是"最佳实践"一般来说这样做。在大多数情况下,现有的常用替代方案之一(Java序列化,JSON,XML等)提供了一个很好的解决方案。

IMO,你应该只考虑"滚动你自己的"格式化(并实现相应的序列化/反序列化代码),如果您有明确要求,或者您有明确证据表明现有备选方案不能工作。民间智慧" XYZ很慢"证据不足。

答案 2 :(得分:2)

我脑子里想到了几件事:

  • 在每条消息或连接协商中包含版本号。它将为您免除巨大的麻烦。最好让发件人知道接收者支持的版本。

  • 除非您发送自然二进制(图像,声音)的数据,否则请使用可读的纯文本(UTF-8)格式。它将帮助解决很多问题。我坚持JSON,但它可能不适合你。 XML的开销很高。

  • 如果您的消息足够长,您可以尝试使用一些众所周知的算法压缩它们,例如gzip(GZIPOutputStream)。

正如您所看到的,这些步骤可以促进服务器与可能的客户端之间的格式开放性和松散耦合。没有人知道您的客户将来必须使用哪种技术:关注制造iPhone客户端?一个HTML5 + JS客户端?同上服务器:)

答案 3 :(得分:0)

对于结构化数据Xml,JSon可能是最佳选择。但是对于简单的平面记录,我建议您考虑使用CSV。您可能会发现它更简单/更快。如果您拥有大量记录,则可以更轻松地管理井。例如加载到电子表格中

相关问题