( c0 g0 Q: B" m. z( p" j. D G7 x' h
二、优酷的标准化实践 8 O0 b0 ^; z; O , o6 v2 [4 [: A1 G1 K% [1.渲染架构标准化2 t. n; z/ U2 v! W3 m
, F$ I, k7 C. ^( z通常一个应用是由一个一个页面组成的,而页面是由什么组成的呢? - d- D K' X% K; u, r$ k) h3 j D( i: U1 d5 N, A) f
我们可以大致分为三个部分:数据,组件和服务。5 H) h. ^. U. R
( Q5 T0 ^' C- D# C
数据模型是业务模型的抽象化产物,是页面的里,它的结构来源于业务的需要,影响着组件的实现。数据从媒资,算法等生产源头通过 CMS(内容管理系统)汇聚而来,通过网络以字节流传输到客户端,客户端下载,解析,转换成对象,或统一保存,或组织分发给每一个显示单元,从而完成其从生产到消费漫漫征途。 + ]. x j6 y! S8 [0 s5 t' A2 D5 [. j) g! X4 G
数据需要贴合业务,如果有一个环节的格式定义出现差异,最终的结果可能就会大不相同,而刷洗数据,转化格式又会带来效率上的降低。而对统一架构和标准化组件来说,我们又希望数据的格式和字段是一致的。如何来解决这一对矛盾获得最优解呢?1 R! c# M7 Z; x# K
: d# F6 _: p' J. ?0 M2 P2 Z" v我们从两个方向进行了尝试,一个是在页面搭建方向上,推进了服务端的数据协议的标准化,之前服务端的数据模型大致都是 page-module-component-item 的多层嵌套结构,它对应了运营同学在搭建页面时,从整体到局部到细节的设计思路和操作行为。我们的标准化思路就是虚化节点定义,明确节点结构。虚化节点定义的意思,我们不再以 page,module 等有具体意思和层级关系的名称作为节点 tag,而是统一为 Node。这样原本有层级关系的结构,就变成了可以任意嵌套的结构。而对于 Node,明确其内部为 level,data[],style[] 和 subNodes[] 等含义明确的标准化结构。而在组件渲染方向上,我们将数据结构演化抽象为从 PO-DTO-DO-VO【备注】的过程。而我们在 VO 这一层去抹平之前的协议差异。7 s9 `' d4 @% @7 h+ W
6 O7 r0 a q! H% N1 H1)组件是页面的表,直接响应用户体验。组件的核心设计原则是组件在不同页面上的复用,为此我们将组件的内部实现分解为 Model,View 和 Presenter 三个部分,各部分之前只以 Contract 约束接口定义。这样三类模块都可以进行不同实现的组合和替换,我们刚才说的在 VO 抹平数据协议差异,就是通过配置不同的 Model 完成的。此外,我们在组件的布局管理使用了 vLayout 的布局混排能力,在配置上通过文件配置进行布局样式上配置和组件 MVP 的搭配,还提供了组件间的通信能力。这些标准化接口的提供,统一了组件的使用环境,大大降低了组件的 UI 开发的难度。% n8 Y+ n# c" i, M6 k. l" q7 ^# M
/ ^8 N Q7 c. w2 k2)服务是页面的神,有了服务页面才是活的。对于服务我们抽象为域内服务和域外服务,域内服务指的是页面范围的视觉动作,比如组件的插入,删除,刷新,加载更多等,这部分能力我们在数据域对象提供了内置的方法,而域外服务则是指对业务中间件和应用基础能力的调用,对于这部分调用,我们在服务能力标准化再介绍。3 T" ]4 [% n; v9 z+ K& P
0 T7 S* O4 M, _# E$ L
在渲染架构标准化的设计中,我们强调了解耦,而这对配置化的实现也带来了便利。通过对页面布局能力的拆解,对组件 MVP 的结构设计,渲染标准化架构把一个组件拆解成了这个组件的容器,容器的 adapter,组件的 MVP 部件,组件交互需要的领域能力,组件交互需要的基础服务等独立部分,可以自由配置组合。在组件承载的业务上,我们也通过代理来进行配置,代理可以拿到页面的上下文,监听业务的消息进行响应,不同的使用场景都遵循着相同规则。. y ]/ a+ m" t- {1 F1 }