代码与代码之外

Code and Beyond

应用面向对象原则进行 protobuf 协议设计

在最近的一个公司项目中,我们实现了一个以面向对象原则为指导的 protobuf 协议(可在线浏览)。目前看来效果不错,已经推广到项目之外,在一定程度上也优化了产品设计。

最开始的需求是实现一个混排的资讯和用户短图文系统,可以不断下拉刷新。开发(我本人)在协议设计时考虑到以后可能会集成更多的可展示对象,设计了一个“抽象帧容器列表”协议。该协议在一年多的产品演进中保持了极好的扩展性,目前除资讯和用户短图文外,还支持推广、话题、Banner、H5、快讯、投票等展示对象。在演进过程中保持了和设计之初一致的概念和约定,并复用了大量协议中的跳转、按钮、内容段等对象。

由于 protobuf 是一个只有结构概念的 IDL,所以这里面使用了少量显式的对象化技巧,类似于在 C 语言中模拟面向对象技术,这方面的案例非常容易获取。

这个协议里几个重要的概念和特点如下:

举例,如下接口:

rpc GetContentList(ContentListRequest) returns(ContentListResponse);

用户需要在 ContentListRequest 填写终端信息、登录信息、附加信息、(区分访问类型的)导航信息、(用以翻页的)最后一帧等。

当 App 或其它服务发起列表请求时,会使用该接口将 ContentListRequest 结构发给服务并获取 ContentListResponse 结构。

message ContentListResponse { 
				
optional StatusInfo status_info = 1; // 请求返回的状态信息, 该结构定义在cell_proxy_common.proto中
repeated AbstructFrame frames = 2; // 请求返回的内容帧
}

服务器将多个可展示数据填加到一个 ContentListResponse 结构的 AbstructFrame 列表。扩展性的关键是这个 AbstructFrame 抽象帧共用体,将其组装成列表的作用是实现混排。

// 抽象帧,每一个帧对应一个展示框
				
message AbstructFrame {
optional string class_type = 1; // eg: BANNER, WEB, NEWS, MASTER, AD, QUICK, NEWSGROUP,// HOTMASTER, PROMOTE 推广, RECOMAND 推荐牛人或栏目, TOPIC_LIST/话题, REPLY/评论 // VOTE/投票
optional string fid = 2; // frame id , eg:BANNER_1, UGC_123, NEWS_123
optional BannerGroup banner = 3;
optional HtmlFrame webf = 4;
optional NewsBrief news = 5;
optional MasterBrief master = 6;
optional QuickGroup quick = 7;
optional NewsGroup news_group = 8;
optional HotMasters hot_masters = 9; // Hotmasters 封装一个source列表, 列表信息为牛人或者栏目
optional PromoteFrame promote = 10; // 推广位
optional TopicHead topics = 11; //精彩话题列表
optional ReplyFrame reply = 12; // 回复帖
optional VoteFrame vote = 13; // 投票帧
}

App 通过解析 AbstructFrame 并判断是否支持该类型 class_type,若支持则取出对应结构而显示。

如一个 AbstructFrame 列表可能顺序装箱了 PromoteFrame、MasterBrief、NewsBrief、MasterBrief 等,App 将它开箱并顺序展示。低版本的 App 可能会丢掉它不认识的 PromoteFrame,只展示后三帧。

阅读这几个结构的定义会发现它们都组合了 Jumper、Source 等结构,这些结构在不同帧中的意义是相同的。

Talk is cheap!阅读协议


2017-04-15 深圳

设计要面向现代化,面向世界,面向未来!