Wire協議緩沖器 一個人必須有一個代碼! -奧馬爾小 由於我們的團隊和項目增長,數據的種類和數量也隨之增加。 成功將您簡單的數據模型轉換為復雜的! 無論您的應用程序將數據存儲到磁盤或網絡傳送信號,該數據的結構和解釋應該是清楚的。 消費者最好的工作,
Wire協議緩沖器
“一個人必須有一個代碼!” -奧馬爾小
由於我們的團隊和項目增長,數據的種類和數量也隨之增加。成功將您簡單的數據模型轉換為復雜的!無論您的應用程序將數據存儲到磁盤或網絡傳送信號,該數據的結構和解釋應該是清楚的。消費者最好的工作,他們了解的數據!
架構描述和文檔數據模型。如果你有數據,你應該有一個架構。
協議緩沖器
谷歌的協議緩沖器都圍繞一個偉大的模式語言:
-
它的跨平台和語言無關。無論您使用的編程語言,你就可以使用原架構與應用程序。
-
原始模式是向后兼容的,面向未來的。作為您的應用程序失去舊的功能和獲得新的可以發展你的架構。
-
它的重點。原架構描述你的數據模型。而已。
下面是一個示例消息定義:
syntax = "proto2";
package squareup.dinosaurs; option java_package = "com.squareup.dinosaurs"; import "squareup/geology/period.proto"; message Dinosaur { // Common name of this dinosaur, like "Stegosaurus". optional string name = 1; // URLs with images of this dinosaur. repeated string picture_urls = 2; optional squareup.geology.Period period = 5; }
這里是一個枚舉定義:
syntax = "proto2";
package squareup.geology; option java_package = "com.squareup.geology"; enum Period { // 145.5 million years ago — 66.0 million years ago. CRETACEOUS = 1; // 201.3 million years ago — 145.0 million years ago. JURASSIC = 2; // 252.17 million years ago — 201.3 million years ago. TRIASSIC = 3; }
這種模式語言是Protocol Buffers的'最大的特點。你甚至可以用它純粹是為了文檔的目的,如描述一個JSON API。
協議緩沖器還定義了符合模式的消息的緊湊二進制編碼。這種編碼快速編碼,快速解碼,小到傳輸,和小存儲。二進制編碼使用數字標簽從架構,像5
的時間
以上。
例如,我們的編碼這個恐龍:
{
name: "Stegosaurus",
period: JURASSIC
}
編碼值僅僅是15個字節:
Hex Description
0a tag: name(1), field encoding: LENGTH_DELIMITED(2). 1 << 3 | 2
0b "Stegosaurus".length()
53 'S'
74 't'
65 'e'
67 'g'
6f 'o'
73 's'
61 'a'
75 'u'
72 'r'
75 'u'
73 's'
28 tag: period(5), field encoding: VARINT(0). 5 << 3 | 0
02 JURASSIC(2)
為什么網?
該協議緩沖器模式語言和二進制編碼都是由谷歌定義。Wire是從廣場的獨立實現,它是專門針對Android和Java設計的。
對於在架構中定義的每個消息的類型,電線產生一個不可變模型類和它的建造者。生成的代碼看起來像你手工編寫代碼:它的記錄,格式化和簡單。電線的API,應該感到在家里誰喜歡程序員有效的Java。
盡管如此,也有一些有趣的設計決策線:
-
電線消息宣布
公眾最終
場,而不是通常的getter方法。這減少了生成的代碼和代碼執行。更少的代碼是Android程序特別有利。 -
電線避免的情況下映射。聲明為字段
picture_urls
在架構產生一個Java領域picture_urls
,而不是傳統的pictureUrls
駱駝情況。雖然名字起初感到尷尬,它每次使用是夢幻般的grep
或更復雜的搜索工具。,Java源代碼和數據模式之間航行時沒有更多的映射。它還提供了一個善意提醒調用代碼,原消息是有點特殊。 -
基本類型總是裝箱。如果字段不存在,它的價值是
零
。這是用於自然可選字段,如恐龍,其周期是未知的。字段也可以為空,由於模式演變:如果明天我們添加一個食肉動物
布爾給我們的消息定義,今天的數據不會有該字段的值。
下面是在緊湊型生成的代碼恐龍
上述定義的消息:
通過Wire協議緩沖編譯器生成的代碼//,不編輯。
//源文件:squareup /恐龍/ dinosaur.proto在9:1
package com.squareup.dinosaurs; import com.squareup.geology.Period; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import com.squareup.wire.WireField; import java.util.List; import okio.ByteString; public final class Dinosaur extends Message<Dinosaur, Dinosaur.Builder> { public static final ProtoAdapter<Dinosaur> ADAPTER = ProtoAdapter.newMessageAdapter(Dinosaur.class); private static final long serialVersionUID = 0L; public static final String DEFAULT_NAME = ""; public static final Period DEFAULT_PERIOD = Period.CRETACEOUS; /** * Common name of this dinosaur, like "Stegosaurus". */ @WireField( tag = 1, adapter = "com.squareup.wire.ProtoAdapter#STRING" ) public final String name; /** * URLs with images of this dinosaur. */ @WireField( tag = 2, adapter = "com.squareup.wire.ProtoAdapter#STRING", label = WireField.Label.REPEATED ) public final List<String> picture_urls; @WireField( tag = 5, adapter = "com.squareup.geology.Period#ADAPTER" ) public final Period period; public Dinosaur(String name, List<String> picture_urls, Period period) { this(name, picture_urls, period, ByteString.EMPTY); } public Dinosaur(String name, List<String> picture_urls, Period period, ByteString unknownFields) { super(unknownFields); this.name = name; this.picture_urls = immutableCopyOf("picture_urls", picture_urls); this.period = period; } @Override public Builder newBuilder() { Builder builder = new Builder(); builder.name = name; builder.picture_urls = copyOf("picture_urls", picture_urls); builder.period = period; builder.addUnknownFields(unknownFields()); return builder; } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof Dinosaur)) return false; Dinosaur o = (Dinosaur) other; return equals(unknownFields(), o.unknownFields()) && equals(name, o.name) && equals(picture_urls, o.picture_urls) && equals(period, o.period); } @Override public int hashCode() { int result = super.hashCode; if (result == 0) { result = unknownFields().hashCode(); result = result * 37 + (name != null ? name.hashCode() : 0); result = result * 37 + (picture_urls != null ? picture_urls.hashCode() : 1); result = result * 37 + (period != null ? period.hashCode() : 0); super.hashCode = result; } return result; } public static final class Builder extends com.squareup.wire.Message.Builder<