Vererbung in Protokollpuffern

Lesezeit: 4 Minuten

Wie geht man mit der Vererbung in Google Protocol Buffers 3.0 um?

Java-äquivalenter Code:

public class Bar {
    String name;
}
public class Foo extends Bar {
    String id;
}

Was wäre ein Proto-äquivalenter Code?

message Bar {
    string name = 1;
}
message Foo {
    string id = 2;
}

  • Die Vererbung wird in Protokollpuffern nicht unterstützt. siehe dies http://stackoverflow.com/questions/29263507/…

    – Yousaf

    20. Dezember 2016 um 13:21 Uhr


  • Mögliches Duplikat von Extending Protobuf Messages

    – iammilind

    31. August 2018 um 6:46 Uhr

Protocol Buffers unterstützt keine Vererbung. Ziehen Sie stattdessen die Verwendung von Komposition in Betracht:

message Foo {
  Bar bar = 1;
  string id = 2;
}

Allerdings gibt es einen Trick, den Sie verwenden können, der wie Vererbung ist – aber ein hässlicher Hack ist, also sollten Sie ihn nur mit Vorsicht verwenden. Wenn Sie Ihre Nachrichtentypen wie folgt definieren:

message Bar {
  string name = 1;
}
message Foo {
  string name = 1;
  string id = 2;
}

Diese beiden Arten sind kompatibelWeil Foo enthält eine Obermenge der Felder von Bar. Das heißt, wenn Sie eine verschlüsselte Nachricht eines Typs haben, können Sie sie als den anderen Typ entschlüsseln. Wenn Sie versuchen, a zu entschlüsseln Bar als Typ Foodas Feld id wird nicht gesetzt (und erhält seinen Standardwert). Wenn Sie a entschlüsseln Foo als Typ Bardas Feld id wird ignoriert. (Beachten Sie, dass dies die gleichen Regeln sind, die beim Hinzufügen neuer Felder zu einem Typ im Laufe der Zeit gelten.)

Sie können dies möglicherweise verwenden, um so etwas wie Vererbung zu implementieren, indem Sie mehrere Typen haben, die alle eine Kopie der Felder der “Superklasse” enthalten. Es gibt jedoch ein paar große Probleme mit diesem Ansatz:

  • Konvertieren eines Nachrichtenobjekts vom Typ Foo tippen Bar, müssen Sie serialisieren und erneut analysieren; Sie können nicht einfach werfen. Dies kann ineffizient sein.
  • Es ist sehr schwierig, der Oberklasse neue Felder hinzuzufügen, da Sie sicherstellen müssen, dass das Feld jeder Unterklasse hinzugefügt wird, und sicherstellen müssen, dass dies keine Feldnummernkonflikte erzeugt.

  • Irgendeine Idee, wie ich den De/Encoder von der Java-API aufrufen würde?

    – Janac Meena

    11. Juli 2019 um 17:35 Uhr

  • Die Verwendung von Bar zum Decodieren von Foo bei der Verwendung von Komposition hat bei mir nicht wirklich funktioniert.

    – gtato

    5. März 2020 um 16:40 Uhr

  • @glato ja, das funktioniert nicht mit Komposition. Es funktioniert nur, wenn ein Typ eine Teilmenge der Felder des anderen Typs enthält, wie in meinem zweiten Beispiel.

    – Kenton Varda

    6. März 2020 um 18:01 Uhr

  • Wie würde das funktionieren, wenn Foo und Bar ein gemeinsames Feld teilen?

    – pooya13

    13. Juli 2020 um 21:26 Uhr

  • @ pooya13 Foo’s Feld wird hide Bar’s gleichnamiges Feld.

    – Homunculus Reticulli

    21. Oktober 2021 um 9:11 Uhr

Siehe die Grundlagen des Protokollpuffers Lernprogramm:

Suchen Sie jedoch nicht nach Möglichkeiten, die der Klassenvererbung ähneln – Protokollpuffer tun das nicht.

  • Irgendeine Idee, warum sie das nicht tun? Ich meine, es klingt nicht nach etwas, das sie hinzufügen wollen, nicht einmal in der Zukunft

    – Frederico Pantuzza

    4. August 2017 um 11:07 Uhr

  • ich denken es kann zu Ineffizienzen führen. Eines der Hauptmerkmale von Porto-Puffer ist es, Dinge effizient zu verpacken. Der einer Variablen zugewiesene niedrigere Wert von Integer sorgt für optimiertes Packen und zweitens müssen sie eindeutig sein. Wenn jetzt mehrere Vererbungsebenen erstellt werden, ist es schwierig, die Ganzzahlen zu verfolgen, die Eigenschaften in den Basisstrukturen zugewiesen sind.

    – Pankaj Garg

    14. September 2017 um 0:06 Uhr

  • Es besteht keine Notwendigkeit, Vererbung hinzuzufügen, sie dient nur dazu, Datensätze von einer Seite auf eine andere Seite zu bringen. Wenn die eine oder andere Seite Berechnungen durchführen möchte, die Vererbungskonstrukte bilden, hat dies keine Konsequenzen für die zu kommunizierenden Daten.

    – Bert Verhees

    29. Juli 2018 um 12:12 Uhr


  • Angesichts der Tatsache, dass die meisten Sprachen, für die Protocol Buffers Bindungen hat, OO sind und Vererbung unterstützen, scheint es ein kleines Versehen für Protobufs zu sein, die Unterstützung für Vererbung auszulassen. Das wäre so monumental dumm wie EJB (nur für die OO-Java-Sprache gebaut), das die Unterstützung für Vererbung weglässt …

    – Volksmann

    20. Juni 2021 um 9:13 Uhr


  • Ich denke, der Hauptgrund, warum es nicht getan wird, ist, dass es das Risiko von ID-Konflikten erhöht, insbesondere wenn es eine Versionsabweichung gibt und eine Seite ein älteres Schema verwendet. Und es ist weniger offensichtlich, dass dies geschieht, da sich die IDs für die “Basisklasse” an anderer Stelle befinden würden, vielleicht nicht einmal in derselben Datei wie die abgeleitete Klasse.

    – Miral

    12. August 2021 um 7:21 Uhr

1145100cookie-checkVererbung in Protokollpuffern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy