我知道这是一个老问题了,但我想我会把我的 2 便士扔进去!
有了 boost,您就有机会在您的课程中编写一些数据验证;这很好,因为数据定义和有效性检查都在一个地方。
使用 GPB,您能做的最好的事情就是将 cmets 放入 .proto 文件中,并希望所有使用它的人都能阅读它、关注它并自行实施有效性检查。
不用说,如果您依靠网络流另一端的其他人以与自己相同的活力来执行此操作,这不太可能且不可靠。此外,如果对有效性的约束发生变化,则需要计划、协调和完成多个代码更改。
因此,我认为 GPB 不适合很少有机会与所有团队成员定期会面和交谈的开发。
==编辑==
我的意思是这样的:
message Foo
{
int32 bearing = 1;
}
现在谁来说bearing 的有效范围是多少?我们可以有
message Foo
{
int32 bearing = 1; // Valid between 0 and 359
}
但这取决于其他人阅读并为其编写代码。例如,如果你编辑它并且约束变为:
message Foo
{
int32 bearing = 1; // Valid between -180 and +180
}
您完全依赖于使用此 .proto 更新其代码的每个人。这是不可靠且昂贵的。
至少使用 Boost 序列化,您正在分发单个 C++ 类,并且可以在其中内置数据有效性检查。如果这些限制条件发生变化,那么除了确保他们使用与您相同版本的源代码外,其他人无需做任何工作。
替代方案
还有一个替代方案:ASN.1。这是古老的,但有一些非常非常方便的东西:
Foo ::= SEQUENCE
{
bearing INTEGER (0..359)
}
注意约束。因此,每当有人使用此 .asn 文件、生成代码时,他们最终都会得到自动检查 bearing 是否介于 0 和 359 之间的代码。如果您更新 .asn 文件,
Foo ::= SEQUENCE
{
bearing INTEGER (-180..180)
}
他们需要做的就是重新编译。无需更改其他代码。
你也可以这样做:
bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360
Foo ::= SEQUENCE
{
bearing INTEGER (bearingMin..<bearingMax)
}
注意<。而且在大多数工具中,bearingMin 和bearingMax 可以在生成的代码中显示为常量。这非常有用。
约束可能非常复杂:
Garr ::= INTEGER (0..10 | 25..32)
看看这个PDF中的第13章;你能做的真是太棒了;
数组也可以被约束:
Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE
{
boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}
ASN.1 是老式的,但仍在积极开发、广泛使用(您的手机经常使用它),并且比大多数其他序列化技术更灵活。我能看到的唯一不足是没有像样的 Python 代码生成器。如果您使用的是 C/C++、C#、Java、ADA,那么免费(C/C++、ADA)和商业(C/C++、C#、JAVA)工具的组合将为您提供很好的服务。
我特别喜欢二进制和基于文本的线格式的广泛选择。这使得它在某些项目中非常方便。有线格式列表目前包括:
- BER(二进制)
- PER(二进制、对齐和未对齐。这是超位效率。例如,限制在
0 和15 之间的INTEGER 将只占用线路上的4 bits)
- OER
- DER(另一个二进制文件)
- XML(也是 XER)
- JSON(全新,工具支持仍在开发中)
加上其他人。
注意最后两个?是的,您可以在 ASN.1 中定义数据结构、生成代码并以 XML 和 JSON 格式发出/使用消息。对于一项始于 1980 年代的技术来说还不错。
版本控制与 GPB 不同。您可以允许扩展:
Foo ::= SEQUENCE
{
bearing INTEGER (-180..180),
...
}
这意味着以后我可以添加到Foo,具有此版本的旧系统仍然可以工作(但只能访问bearing 字段)。
我对 ASN.1 的评价很高。处理起来可能很痛苦(工具可能要花钱,生成的代码不一定漂亮,等等)。但是这些限制是一个真正奇妙的功能,它一次又一次地为我节省了大量的心痛。当编码器/解码器报告他们生成了 duff 数据时,开发人员会发牢骚。
其他链接:
观察
共享数据:
- 代码优先方法(例如 Boost 序列化)将您限制为使用原始语言(例如 C++),或者迫使您使用另一种语言做大量额外工作
- 首先使用架构更好,但是
- 其中很多在共享合同中留下了很大的空白(即没有限制)。 GPB 在这方面很烦人,因为它在其他方面非常好。
- 有些有限制(例如 XSD、JSON),但受到不完整的工具支持。
- 例如,Microsoft 的 xsd.exe 主动忽略 xsd 文件中的约束(MS 的借口实在是微不足道)。 XSD 很好(从约束的角度来看),但如果你不能相信其他人会使用一个好的 XSD 工具来为他/她强制执行它们,那么 XSD 的价值就会降低
- JSON 验证器没问题,但它们一开始就无法帮助您形成 JSON,并且不会自动调用。无法保证向您发送 JSON 消息的人已经通过验证器运行了它。您必须记得自己验证。
- ASN.1 工具似乎都实现了约束检查。
所以对我来说,ASN.1 做到了。它是最不可能导致其他人犯错的那个,因为它具有正确的功能,并且所有工具似乎都在努力完全实现这些功能,并且对于大多数用途而言,它是语言中立的。
说实话,如果 GPB 添加了约束机制,那将是赢家。 XSD 很接近,但这些工具几乎都是垃圾。如果有其他语言的不错的代码生成器,JSON 模式会非常好。
如果 GPB 添加了约束(注意:这不会改变任何有线格式),那将是我向所有人推荐的几乎所有用途的约束。虽然 ASN.1 的 uPER 对于无线电链路非常有用。