¿Por qué Protobuf 3 hizo todos los campos en los mensajes opcionales?


15

La sintaxis 3 de protobuf hizo que todos los campos fueran opcionales eliminando las palabras clave requiredy optionalde la sintaxis proto2 anterior. Al leer algunos comentarios de los desarrolladores , parece que se hizo para mejorar la compatibilidad binaria hacia adelante / hacia atrás.

Pero para mí, eso podría hacerse cumplir simplemente versionando los nombres de los paquetes, digamos com.example.messages.v1y luego permitiendo que los clientes implementen deserializadores que entiendan. Al mismo tiempo, elimina algunos contratos establecidos como un tipo que son útiles desde el punto de vista de la ingeniería de software. Por ejemplo si tengo

message Location {
   double latitude = 1;
   double longitude = 2;
}

En proto3 es posible crear un medio respaldado pero perfectamente válido Locational no proporcionar uno de los campos obligatorios.

¿No es un gran inconveniente al crear un formato de serialización basado en esquemas para el intercambio de datos entre clientes? ¿No es peor mover el código de validación adicional a cada cliente comprobando que todos los campos obligatorios tienen valores válidos?


Respuestas:


13

proto3 realiza una serie de cambios destinados (según tengo entendido) a hacer que sea mucho más utilizable en escenarios multiplataforma. El seguimiento explícito de "asignado" frente a "no asignado pero que informa el valor predeterminado" puede ser muy difícil de implementar en algunas de las plataformas de destino, y también puede ser confuso de usar. Como tal, proto3 adopta un enfoque mucho más simple:

  • el valor predeterminado implícito es el valor cero natural (números / enumeraciones), falso (booleanos) o la cadena vacía (cadenas)
  • solo se permite el valor predeterminado implícito; no se permiten otros valores predeterminados
  • si un campo tiene ese valor predeterminado, no se serializa; no importa si fue asignado explícitamente a cero / falso / cadena vacía versus nunca asignado
  • debido a esto, no existe el concepto de "requerido", ya que "se le asignó explícitamente un valor cero" y "nunca se le asignó un valor" parece idéntico

En proto3 es posible crear una ubicación con respaldo medio pero perfectamente válida al no proporcionar uno de los campos obligatorios.

El otro valor es: cero. El hecho de que no lo haya asignado explícitamente a cero es discutible. Depende de usted si esto es deseable o no, pero tiene sentido para mí y es cómo funciona una gran cantidad de "inicializar un nuevo objeto / estructura" en una amplia gama de plataformas.

¿No es peor mover el código de validación adicional a cada cliente comprobando que todos los campos obligatorios tienen valores válidos?

¡No hay nada que validar! El diseño es exactamente lo que sería si el valor cero se asignara explícitamente. Si eso es legal, es legal. Si es ilegal (porque cero no tiene sentido para usted), es ilegal; pero sería ilegal si fuera explícito o implícito. La cantidad de validación involucrada no cambia.

¿No es un gran inconveniente al crear un formato de serialización basado en esquemas para el intercambio de datos entre clientes?

Por lo general, no, no ... especialmente porque la versión del esquema es explícita. Si desea usar proto2: use proto2. Nada cambia automáticamente.


Me pregunto qué les compra "solo cero natural por defecto", ya que protobuf no es realmente utilizable sin algún tipo de esquema. Asegurar valores predeterminados consistentes no suena mucho más difícil que garantizar esquemas consistentes en primer lugar.
CodesInChaos

1
@CodesInChaos eso es interesante, porque he estado haciendo protofoto sin esquema durante ... bueno, para siempre :) en protobuf-net, se espera que la mayoría de los usuarios sean sin código y sin esquema. Y curiosamente (para mí, al menos) la mayoría de las estrategias predeterminadas de "mantenerlo simple, estúpido" que usa protobuf-net son exactamente las mismas que las que proto3 eligió usar. No voy a afirmar que esto valida mis decisiones partidistas al azar, pero ... lo hace totalmente :)
Marc Gravell

Considero que una clase C # es un tipo de esquema y ciertamente puede especificar valores predeterminados a través de atributos. Compare esto con, por ejemplo, msgpack o json, que pueden crear una estructura de datos significativa sin ningún tipo de esquema.
CodesInChaos

@CodesInChaos estuvo de acuerdo y señaló - y sí, protobuf-net observará y respetará cualquier declaración de este tipo
Marc Gravell
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.