协议缓冲区和面向对象的设计(Protocol buffer and OO design)

2019-07-30 18:31发布

我使用协议缓冲器作为在客户端 - 服务器体系结构的线的数据格式。 域对象(的Java bean)将通过以下的生命周期。

  1. 用于客户端业务逻辑
  2. 转换为protobuf的格式
  3. 发送到服务器
  4. 转换回域对象
  5. 用于服务器端业务逻辑

“协议缓冲器和OO设计”的Protobuf文档中部分建议内合适的领域模型包装生成的类。

我想找到出最好的appoach。

对于如我有一个简单的协议定义。

package customer;

option java_package = "com.example";
option java_outer_classname = "CustomerProtos";

message Customer {
    required string name = 1;
    optional string address = 2;
}

这是领域模型是如何定义的。 正如你所看到的,数据完全存储在原生成器对象。

package com.example;

public class CustomerModel
{
    private CustomerProtos.Customer.Builder builder = CustomerProtos.Customer.newBuilder();

    public String getName()
    {
        return builder.getName();
    }

    public void setName(String name)
    {
        builder.setName(name);
    }

    public String getAddress()
    {
        return builder.getAddress();
    }

    public void setAddress(String address)
    {
        builder.setAddress(address);
    }

    public byte[] serialize()
    {
        return builder.build().toByteArray();
    }

}

这是一个好的做法呢? 因为这些对象在生命周期的各个阶段使用,但是我们只需要在客户端 - 服务器传输阶段protocolbuf格式。

是否有访问原器类的getter / setter方法时,特别是当原定义是复杂的,嵌套的任何性能问题?

Answer 1:

我有一个协议缓冲区没有经验,但是我建议实施针对特定的序列化/转让框架域对象。 你可能会感到遗憾的是未来。

因为你希望你的域名很容易理解和可重用/维护在未来的领域对象和软件应用程序的逻辑应该尽可能独立从具体执行问题(在你的情况系列化/传输)。

如果你要定义你的域对象的系列化独立/传送的,你有两个选择:

  1. 序列化/转让之前,将信息复制到协议缓冲区特定的对象,并将它们发送到服务器。 在那里,你将不得不将信息复制回你的域对象。
  2. 使用非协议串行化库像KRYO或ProtoStuff到你的域对象直接传输到服务器。

选项1的缺点是您的域定义的两个时间(这是不希望相对于修饰)和信息的复制(其产生易错和非维护的代码)。

选项2的缺点是你失去架构演进 (虽然ProtoStuff显然支持的话 )和完整的(可能很大)对象图被序列化和转移。 虽然可以修剪对象图(手动或使用JGT序列化/转移之前)。



Answer 2:

我们已经有了一个protobuf的转换器解决您的领域模型对象到谷歌的Protobuf消息,反之亦然转型的问题。

如何使用它:

必须被转化成protobuf的消息必须满足的条件域模型类:

  • 类具有由一个包含对相关的protobuf消息类别参考@ProtoClass annotaion进行标记。
  • 类字段必须由@ProtoField annotaion标记。 这些字段必须有getter和setter方法。

例如:

@ProtoClass(ProtobufUser.class)
public class User {

    @ProtoField
    private String name;
    @ProtoField
    private String password;

    // getters and setters for 'name' and 'password' fields
    ...
}

代码转换的用户例如到相关protobuf的消息:

User userDomain = new User();
...
ProtobufUser userProto = Converter.create().toProtobuf(ProtobufUser.class, userDomain);

代码转换落后:

User userDomain = Converter.create().toDomain(User.class, userProto);

对象列表的转换是类似于单个对象转换。



文章来源: Protocol buffer and OO design