对Java协议缓冲区对象进行小改动

36

我希望对Java协议缓冲对象树进行小修改。

我可以使用.getBuilder()方法创建一个新对象,该对象是旧对象的副本,并进行一些更改。

当在深层级别上完成此操作时,代码变得丑陋:

Quux.Builder quuxBuilder = foo.getBar().getBaz().getQuux().toBuilder()
Baz.Builder bazBuilder = foo.getBar().getBaz().toBuilder()
Bar.Builder barBuilder = foo.getBar().toBuilder()
Foo.Builder fooBuilder = foo.toBuilder()

quuxBuilder.setNewThing(newThing);
bazBuilder.setQuux(quuxBuilder);
barBuilder.setBaz(bazBuilder);
fooBuilder.setBar(barBuilder);

Foo newFoo = fooBuilder.build();

(这只是4个级别,我通常要处理5-8个级别。)

有更好的方法吗?

1个回答

42

另一个选项是(我想,已经有一段时间了):

Foo.Builder fooBuilder = foo.toBuilder();
fooBuilder.getBarBuilder().getBazBuilder().getQuuxBuilder()
    .setNewThing(newThing);
newFoo = fooBuilder.build();
注意这并不更有效率;仍然会复制foo、bar、baz和quux。

请注意,这并不更加高效;您仍将复制foo、bar、baz和quux。


2
谢谢,我真的很惊讶这个方法可行。我没有意识到在fooBuilder的上下文中fooBuilder.getBarBuilder()返回了一个Bar.Builder。测试套件没有显示任何错误,所以它是有效的。代码量仍然随深度线性增长,但至少缩小了三倍。 - fadedbee
5
如果您愿意,长期保持对象处于“Builder”形式而不是不可变的消息形式,然后可以保留指向要修改的特定子生成器的指针并反复修改它。但要注意可变对象通常存在的设计问题。 - Kenton Varda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接