我希望有人能够说明Microsoft Bond运行时架构(SchemaDef)的常见用例。我知道在编译时不知道模式定义时会使用这些方法,但是如果对象的形状是可变的并且经常更改,那么运行时生成的模式可以提供什么好处?
我的用例是业务用户(通过规则引擎)控制对象的形状。可以想象,他们可以做各种可能破坏我们向后兼容性的事情(例如,反转对象上字段的顺序)。如果我们计划保留用户创建的所有对象版本,是否有任何方法可以使用Bond运行时模式来管理向后/向前兼容性?我假设没有,好像他们从此倒转了一样:
0: int64 myInt;
1: string myString;
对此
0: string myString;
1: int64 myInt;
我期望运行时错误。这意味着使用运行时模式管理对象不会为我提供太多帮助。
在什么情况下,运行时模式实际上会有用?
谢谢!
运行时模式的一些用途是:
如果您可以主动拒绝不兼容的架构,那么您的案例就像是架构验证。我在一个使用引擎盖下使用Bond的系统上工作,并采用了这种方法。有一个明确的“更改此实体的架构”操作可验证两个架构是否相互兼容。
我不知道您系统中的数据流,因此可能无法进行这种验证。在这种情况下,您可以使用运行时模式以及业务用户提供的一些规则在不同形状之间进行转换。
从“简单二进制”中反序列化时,读取者必须知道编写者使用的确切架构,否则它无法解释字节,从而可能导致静默数据损坏。
如果架构进行以下更改,则可能会发生这种损坏:
// starting struct
struct Foo
{
0: uint8 f1;
1: uint16 f2;
}
Foo { f1: 1, f2: 2}
is的简单二进制序列化表示形式0x01 0x02 0x00
。
现在让我们将模式更改为:
// changed struct
struct Foo
{
0: uint8 f1;
// It's OK to remove an optional field.
// 1: uint16 f2;
2: uint8 f3;
3: uint8 f4;
}
如果0x01 0x02 0x00
使用此模式反序列化,则将得到Foo { f1: 1, f3: 2, f4: 0}
。请注意,它f3
是2,这是不正确的:应该为0。使用旧Foo的运行时模式,读者将知道第二个和第三个字节对应于此后已删除的字段,并且可以跳过它们,从而导致预期的Foo { f1:1, f3: 0, f4: 0 }
。
一些使用Bond的系统具有与普通Bond规则不同的模式演化规则。在接受给定类型的结构之前,或在例如已知模式的存储库中注册这样的模式之前,可以使用运行时模式来强制执行此类规则(例如,检查类型以强制执行不使用任何集合的规则)。
您还可以遍历两个模式来确定它们彼此兼容。如果Bond本身提供了这样的API,那就太好了,这样就不必一次又一次地重新实现它。我已经针对此类API打开了GitHub问题。
使用运行时模式,您可以获得有关该结构的额外信息,包括诸如字段名称之类的信息。(二进制编码协议省略了字段名称,而是依赖于字段ID。)您可以使用此附加信息来完成诸如创建特定于每个字段的GUI控件之类的操作。
在C ++中,MapTo
可以使用转换将给定规则的结构转换为不兼容形状的结构。有一个这样的示例,该示例利用运行时模式派生规则。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句