Estoy evaluando Google Protocol Buffers para un servicio basado en Java (pero espero patrones agnósticos de lenguaje). Tengo dos preguntas:
La primera es una pregunta general amplia:
¿Qué patrones estamos viendo que usa la gente? Dichos patrones están relacionados con la organización de la clase (por ejemplo, mensajes por archivo .proto, empaquetado y distribución) y la definición del mensaje (por ejemplo, campos repetidos versus campos encapsulados repetidos *), etc.
Hay muy poca información de este tipo en las páginas de ayuda de Google Protobuf y en los blogs públicos, mientras que hay una gran cantidad de información para protocolos establecidos como XML.
También tengo preguntas específicas sobre los siguientes dos patrones diferentes:
Represente los mensajes en archivos .proto, empaquételos como un contenedor separado y envíelos a los consumidores del servicio, lo cual es básicamente el enfoque predeterminado, supongo.
Haga lo mismo, pero también incluya envoltorios hechos a mano (¡no subclases!) Alrededor de cada mensaje que implemente un contrato que soporte al menos estos dos métodos (T es la clase de envoltura, V es la clase de mensaje (usando sintaxis genérica pero simplificada por brevedad) :
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()); }
Una ventaja que veo con (2) es que puedo ocultar las complejidades introducidas por V.newBuilder().addField().build()
y agregar algunos métodos significativos como isOpenForTrade()
o isAddressInFreeDeliveryZone()
etc. en mis envoltorios. La segunda ventaja que veo con (2) es que mis clientes manejan objetos inmutables (algo que puedo imponer en la clase wrapper).
Una desventaja que veo con (2) es que duplico el código y tengo que sincronizar mis clases de contenedor con archivos .proto.
¿Alguien tiene mejores técnicas o más críticas sobre cualquiera de los dos enfoques?
* Al encapsular un campo repetido me refiero a mensajes como este:
message ItemList {
repeated item = 1;
}
message CustomerInvoice {
required ShippingAddress address = 1;
required ItemList = 2;
required double amountPayable = 3;
}
en lugar de mensajes como este:
message CustomerInvoice {
required ShippingAddress address = 1;
repeated Item item = 2;
required double amountPayable = 3;
}
Me gusta este último pero estoy feliz de escuchar argumentos en contra.