J'évalue les tampons de protocole Google pour un service basé sur Java (mais j'attends des schémas indépendants du langage). J'ai deux questions:
La première est une vaste question générale:
Quels modèles voyons-nous les gens utiliser? Ces schémas étant liés à l'organisation des classes (par exemple, messages par fichier .proto, conditionnement et distribution) et à la définition des messages (par exemple, champs répétés vs champs encapsulés répétés *), etc.
Il existe très peu d'informations de ce type sur les pages d'aide de Google Protobuf et les blogs publics, tandis qu'il existe une tonne d'informations pour les protocoles établis tels que XML.
J'ai également des questions spécifiques sur les deux modèles suivants:
Représentez les messages dans des fichiers .proto, empaquetez-les dans un bocal séparé et envoyez-le aux clients cibles du service - ce qui est fondamentalement l'approche par défaut, je suppose.
Faites de même, mais incluez également des wrappers fabriqués à la main (pas des sous-classes!) Autour de chaque message qui implémentent un contrat prenant en charge au moins ces deux méthodes (T est la classe wrapper, V est la classe du message (en utilisant des génériques mais une syntaxe simplifiée pour plus de concision) :
public V toProtobufMessage() { V.Builder builder = V.newBuilder(); for (Item item : getItemList()) { builder.addItem(item); } return builder.setAmountPayable(getAmountPayable()). setShippingAddress(getShippingAddress()). build(); } public static T fromProtobufMessage(V message_) { return new T(message_.getShippingAddress(), message_.getItemList(), message_.getAmountPayable()); }
Un avantage que je vois avec (2) est que je peux cacher les complexités introduites par V.newBuilder().addField().build()
et ajouter des méthodes significatives telles que isOpenForTrade()
ou isAddressInFreeDeliveryZone()
etc. dans mes wrappers. Le deuxième avantage que je vois avec (2) est que mes clients traitent des objets immuables (quelque chose que je peux appliquer dans la classe wrapper).
Un inconvénient que je vois avec (2) est que je duplique du code et que je dois synchroniser mes classes wrapper avec des fichiers .proto.
Quelqu'un a-t-il de meilleures techniques ou d'autres critiques sur l'une des deux approches?
* En encapsulant un champ répété, je veux dire des messages comme celui-ci:
message ItemList {
repeated item = 1;
}
message CustomerInvoice {
required ShippingAddress address = 1;
required ItemList = 2;
required double amountPayable = 3;
}
au lieu de messages comme celui-ci:
message CustomerInvoice {
required ShippingAddress address = 1;
repeated Item item = 2;
required double amountPayable = 3;
}
J'aime ce dernier, mais je suis heureux d'entendre des arguments contre.