ทำไม Protobuf 3 ทำให้ฟิลด์ทั้งหมดในข้อความเป็นตัวเลือก?


15

ไวยากรณ์ 3 ของ protobuf ทำให้ฟิลด์ทั้งหมดเป็นตัวเลือกที่ทิ้งคำหลักrequiredและoptionalจากไวยากรณ์ proto2 ก่อนหน้า อ่านความคิดเห็นจากนักพัฒนาดูเหมือนว่ามันทำเพื่อเพิ่มความเข้ากันได้ไบนารีไปข้างหน้า / ถอยหลัง

แต่สำหรับฉันนั้นสามารถบังคับใช้ได้โดยเพียงแค่กำหนดชื่อแพคเกจพูดcom.example.messages.v1แล้วปล่อยให้ลูกค้าใช้ deserializers ที่พวกเขาเข้าใจ ในขณะเดียวกันก็ลบสัญญาบางฉบับที่ระบุว่าเป็นประเภทที่มีประโยชน์จากมุมมองด้านวิศวกรรมซอฟต์แวร์ เช่นถ้าฉันมี

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

ใน proto3 เป็นไปได้ที่จะสร้างการสำรองข้อมูลครึ่งหนึ่ง แต่ใช้ได้อย่างสมบูรณ์แบบLocationโดยไม่ได้ให้ข้อมูลหนึ่งในฟิลด์ที่จำเป็น

นี่เป็นข้อเสียเปรียบครั้งใหญ่เมื่อสร้างรูปแบบการทำให้เป็นอนุกรมตามสคีมาสำหรับการแลกเปลี่ยนข้อมูลระหว่างลูกค้าหรือไม่ การย้ายรหัสตรวจสอบพิเศษเพิ่มเติมไปยังไคลเอนต์แต่ละรายไม่ได้แย่ไปกว่าการตรวจสอบว่าฟิลด์ที่จำเป็นทั้งหมดมีค่าที่ถูกต้องหรือไม่


คำตอบ:


13

proto3 ทำการเปลี่ยนแปลงจำนวนมากโดยมีจุดมุ่งหมาย (อย่างที่ฉันเข้าใจ) เพื่อทำให้สามารถใช้งานได้มากขึ้นในสถานการณ์ข้ามแพลตฟอร์ม การติดตามอย่างชัดเจนของ "มอบหมาย" กับ "ไม่ได้มอบหมาย แต่การรายงานค่าเริ่มต้น" อาจเป็นเรื่องยากมากที่จะนำไปใช้กับแพลตฟอร์มเป้าหมายบางอย่างและอาจทำให้สับสนในการใช้งาน ดังนั้น proto3 จึงใช้วิธีที่ง่ายกว่ามาก:

  • นัยค่าเริ่มต้นเป็นธรรมชาติค่าเป็นศูนย์ (ตัวเลข / enums) เท็จ (บูลีน) หรือสตริงที่ว่างเปล่า (สตริง)
  • เพียงเริ่มต้นที่ได้รับอนุญาตโดยปริยาย; ไม่อนุญาตให้ใช้ค่าเริ่มต้นอื่น ๆ
  • ถ้าเขตข้อมูลมีค่าเริ่มต้นนั้นมันจะไม่ต่อเนื่อง; มันไม่สำคัญว่าจะได้รับมอบหมายอย่างชัดเจนให้เป็นศูนย์ / เท็จ / สตริงว่างเปล่า vs ไม่เคยได้รับมอบหมาย
  • ด้วยเหตุนี้จึงไม่มีแนวคิดของ "จำเป็น" เนื่องจาก "กำหนดค่าศูนย์อย่างชัดเจน" และ "ไม่เคยกำหนดค่า" อย่างชัดเจน

ใน proto3 มีความเป็นไปได้ที่จะสร้างที่อยู่สำรองครึ่งหนึ่ง แต่ตำแหน่งที่ถูกต้องสมบูรณ์โดยไม่ได้ให้ข้อมูลหนึ่งในฟิลด์ที่จำเป็น

ค่าอื่น ๆ คือ: ศูนย์ ความจริงที่ว่าคุณไม่ได้กำหนดอย่างชัดเจนให้กับศูนย์คือ moot ไม่ว่าสิ่งนี้จะขึ้นอยู่กับคุณหรือไม่ แต่ก็สมเหตุสมผลสำหรับฉันและเป็นวิธีการ "กำหนดค่าเริ่มต้นวัตถุ / โครงสร้างใหม่" จำนวนมากบนแพลตฟอร์มที่หลากหลาย

การย้ายรหัสตรวจสอบพิเศษเพิ่มเติมไปยังไคลเอนต์แต่ละรายไม่ได้แย่ไปกว่าการตรวจสอบว่าฟิลด์ที่จำเป็นทั้งหมดมีค่าที่ถูกต้องหรือไม่

ไม่มีอะไรจะตรวจสอบ! เลย์เอาต์คือสิ่งที่มันจะเป็นถ้าค่าศูนย์ได้รับมอบหมายอย่างชัดเจน หากถูกกฎหมายก็ถือว่าถูกกฎหมาย หากเป็นสิ่งผิดกฎหมาย (เพราะศูนย์ไม่สมเหตุสมผลสำหรับคุณ) แสดงว่าผิดกฎหมาย แต่มันจะผิดกฎหมายไม่ว่าจะชัดเจนหรือโดยปริยาย จำนวนการตรวจสอบที่เกี่ยวข้องไม่เปลี่ยนแปลง

นี่เป็นข้อเสียเปรียบครั้งใหญ่เมื่อสร้างรูปแบบการทำให้เป็นอนุกรมตามสคีมาสำหรับการแลกเปลี่ยนข้อมูลระหว่างลูกค้าหรือไม่

ไม่ปกติไม่ ... โดยเฉพาะอย่างยิ่งเนื่องจากเวอร์ชันของสคีมานั้นชัดเจน ถ้าคุณต้องการใช้ proto2: ใช้ proto2 ไม่มีอะไรเปลี่ยนแปลงโดยอัตโนมัติ


ฉันสงสัยว่า "ศูนย์ธรรมชาติเท่านั้นที่เป็นค่าเริ่มต้น" ซื้ออะไรเนื่องจากโปรโตบูฟไม่สามารถใช้งานได้จริงหากไม่มีสคีมา การตรวจสอบให้แน่ใจว่าค่าเริ่มต้นที่สอดคล้องกันนั้นไม่ได้ฟังดูหนักไปกว่าการสร้างแบบแผนที่สอดคล้องกันตั้งแต่แรก
CodesInChaos

1
@CodesInChaos เป็นสิ่งที่น่าสนใจเพราะฉันได้ทำโปรโตฟูฟสคีมาสำหรับ ... ดีตลอดไป :) ในโปรโตบูฟเน็ตเราคาดว่าผู้ใช้ส่วนใหญ่จะเป็นรหัสแรกและสคีมาน้อย และที่น่าสนใจ (สำหรับฉันอย่างน้อย) ส่วนใหญ่ของกลยุทธ์การเริ่มต้นที่ "ทำให้มันง่ายโง่" ที่การใช้โปโตฟ - เน็ตนั้นเหมือนกับโปรโต 3 ที่เลือกใช้ ฉันจะไม่อ้างว่าสิ่งนี้ตรวจสอบความถูกต้องในการตัดสินใจของกลุ่มหัวรุนแรงของฉัน แต่ ... มันทำอย่างสมบูรณ์ :)
Marc Gravell

ฉันพิจารณาสคีมาเป็นคลาส C # และคุณสามารถระบุค่าเริ่มต้นผ่านแอตทริบิวต์ได้อย่างแน่นอน เปรียบเทียบสิ่งนี้กับตัวอย่างเช่น msgpack หรือ json ซึ่งสามารถสร้างโครงสร้างข้อมูลที่มีความหมายโดยไม่มีสคีมาใด ๆ
CodesInChaos

@CodesInChaos เห็นด้วยและสังเกตเห็น - และใช่โปรโตฟฟูสุทธิจะสังเกตและเคารพประกาศดังกล่าว
Marc Gravell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.