https://github.com/square/wire
ire协议缓冲器 一个人必须有一个代码! -奥马尔小 由于我们的团队和项目增长,数据的种类和数量也随之增加。 成功将您简单的数据模型转换为复杂的! 无论您的应用程序将数据存储到磁盘或网络传送信号,该数据的结构和解释应该是清楚的。 消费者最好的工作,
“一个人必须有一个代码!” -奥马尔小
由于我们的团队和项目增长,数据的种类和数量也随之增加。成功将您简单的数据模型转换为复杂的!无论您的应用程序将数据存储到磁盘或网络传送信号,该数据的结构和解释应该是清楚的。消费者最好的工作,他们了解的数据!
架构描述和文档数据模型。如果你有数据,你应该有一个架构。
谷歌的协议缓冲器都围绕一个伟大的模式语言:
它的跨平台和语言无关。无论您使用的编程语言,你就可以使用原架构与应用程序。
原始模式是向后兼容的,面向未来的。作为您的应用程序失去旧的功能和获得新的可以发展你的架构。
它的重点。原架构描述你的数据模型。而已。
下面是一个示例消息定义:
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