23

クライアントサーバーアーキテクチャのワイヤデータ形式としてプロトコルバッファを使用しています。ドメインオブジェクト(Java Beans)は、次のライフサイクルを通過します。

  1. クライアント側のビジネスロジックで使用
  2. protobuf形式に変換
  3. サーバーに送信
  4. ドメインオブジェクトに変換して戻す
  5. サーバー側のビジネスロジックで使用

ProtoBufドキュメントの「ProtocolBuffersandOO Design」セクションでは、生成されたクラスを適切なドメインモデル内にラップすることを推奨しています。

最高のアプローチを見つけたいと思います。

たとえば、私は単純なプロト定義を持っています。

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形式のみであるためです。

特にプロト定義が複雑でネストされている場合に、プロトビルダークラスのゲッター/セッターメソッドにアクセスするときにパフォーマンスの問題はありますか?

4

2 に答える 2

16

私はプロトコルバッファの経験がありませんが、特定のシリアル化/転送フレームワークに合わせて調整されたドメインオブジェクトを実装することはお勧めしません。将来、それを後悔するかもしれません。

ドメインオブジェクトとソフトウェアアプリケーションのロジックは、特定の実装の問題(この場合はシリアル化/転送)から可能な限り独立している必要があります。これは、ドメインを理解しやすく、将来的に再利用/保守できるようにするためです。

シリアル化/転送とは別にドメインオブジェクトを定義する場合は、次の2つのオプションがあります。

  1. シリアル化/転送する前に、情報をプロトコルバッファの特定のオブジェクトにコピーし、それらをサーバーに送信します。そこで、情報をドメインオブジェクトにコピーして戻す必要があります。
  2. KryoProtoStuffなどの非プロトコルシリアル化ライブラリを使用して、ドメインオブジェクトをサーバーに直接転送します。

オプション1の欠点は、ドメインが2回定義されていること(変更に関しては望ましくない)と情報のコピー(エラーが発生しやすく、保守が不可能なコードが生成されること)です。

オプション2の欠点は、スキーマの進化が失われ(ProtoStuffは明らかにそれをサポートしているようですが)、完全な(潜在的に大きな)オブジェクトグラフがシリアル化されて転送されることです。ただし、シリアル化/転送の前に、オブジェクトグラフを(手動またはJGTを使用して)整理することができます。

于 2013-05-03T13:51:18.550 に答える
4

ドメインモデルオブジェクトをGoogleProtobufメッセージに、またはその逆に変換する問題を解決するために、protobuf-converterを作成しました。

それの使い方:

protobufメッセージに変換する必要があるドメインモデルクラスは、次の条件を満たす必要があります。

  • クラスは、関連するprotobufメッセージクラスへの参照を含む@ProtoClass注釈でマークする必要があります。
  • クラスフィールドは、 @ProtoField注釈でマークする必要があります。これらのフィールドには、ゲッターとセッターが必要です。

例えば:

@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);

オブジェクトのリストの変換は、単一オブジェクトの変換に似ています。

于 2016-05-11T09:29:15.700 に答える