5 O& _; h5 m$ [# B& k X. S1 ]
二、优酷的标准化实践* `0 Q3 k2 u: H
! j# o- v6 B+ C! j& q
1.渲染架构标准化, [* \1 _' m. ]: b; C
# n) p) q2 M6 [, A8 s' f) n) L+ V, A) b; M
通常一个应用是由一个一个页面组成的,而页面是由什么组成的呢?* M2 h( V. `0 ~4 d
( S) }$ A1 ?! g5 J( n
我们可以大致分为三个部分:数据,组件和服务。6 J; V" f1 e2 y& e. e3 E2 J
. I% [5 d0 A& k, S
数据模型是业务模型的抽象化产物,是页面的里,它的结构来源于业务的需要,影响着组件的实现。数据从媒资,算法等生产源头通过 CMS(内容管理系统)汇聚而来,通过网络以字节流传输到客户端,客户端下载,解析,转换成对象,或统一保存,或组织分发给每一个显示单元,从而完成其从生产到消费漫漫征途。 4 n4 {9 C( D/ z: g; ]5 L I% y- ^; h3 \
数据需要贴合业务,如果有一个环节的格式定义出现差异,最终的结果可能就会大不相同,而刷洗数据,转化格式又会带来效率上的降低。而对统一架构和标准化组件来说,我们又希望数据的格式和字段是一致的。如何来解决这一对矛盾获得最优解呢?. f; [8 y9 _' Z! g+ z. J
! a9 l$ y$ q4 {我们从两个方向进行了尝试,一个是在页面搭建方向上,推进了服务端的数据协议的标准化,之前服务端的数据模型大致都是 page-module-component-item 的多层嵌套结构,它对应了运营同学在搭建页面时,从整体到局部到细节的设计思路和操作行为。我们的标准化思路就是虚化节点定义,明确节点结构。虚化节点定义的意思,我们不再以 page,module 等有具体意思和层级关系的名称作为节点 tag,而是统一为 Node。这样原本有层级关系的结构,就变成了可以任意嵌套的结构。而对于 Node,明确其内部为 level,data[],style[] 和 subNodes[] 等含义明确的标准化结构。而在组件渲染方向上,我们将数据结构演化抽象为从 PO-DTO-DO-VO【备注】的过程。而我们在 VO 这一层去抹平之前的协议差异。7 N- H# g, f; b6 y
4 W5 t3 H! e5 N! D- M6 I0 F, k
1)组件是页面的表,直接响应用户体验。组件的核心设计原则是组件在不同页面上的复用,为此我们将组件的内部实现分解为 Model,View 和 Presenter 三个部分,各部分之前只以 Contract 约束接口定义。这样三类模块都可以进行不同实现的组合和替换,我们刚才说的在 VO 抹平数据协议差异,就是通过配置不同的 Model 完成的。此外,我们在组件的布局管理使用了 vLayout 的布局混排能力,在配置上通过文件配置进行布局样式上配置和组件 MVP 的搭配,还提供了组件间的通信能力。这些标准化接口的提供,统一了组件的使用环境,大大降低了组件的 UI 开发的难度。7 u% a7 \+ V' ^; t) z& Q4 E7 ~$ a
' ] L/ b1 T6 t' s8 n* u
2)服务是页面的神,有了服务页面才是活的。对于服务我们抽象为域内服务和域外服务,域内服务指的是页面范围的视觉动作,比如组件的插入,删除,刷新,加载更多等,这部分能力我们在数据域对象提供了内置的方法,而域外服务则是指对业务中间件和应用基础能力的调用,对于这部分调用,我们在服务能力标准化再介绍。6 z8 U0 N/ v+ O( V& ~+ o) Z
$ y. J2 h7 B; ]' D4 k1 `, e. G" {在渲染架构标准化的设计中,我们强调了解耦,而这对配置化的实现也带来了便利。通过对页面布局能力的拆解,对组件 MVP 的结构设计,渲染标准化架构把一个组件拆解成了这个组件的容器,容器的 adapter,组件的 MVP 部件,组件交互需要的领域能力,组件交互需要的基础服务等独立部分,可以自由配置组合。在组件承载的业务上,我们也通过代理来进行配置,代理可以拿到页面的上下文,监听业务的消息进行响应,不同的使用场景都遵循着相同规则。1 j# d7 X' H# \9 E. S D
8 M, d: ]0 T h2 i通过一系列的标准化工作,实际上改变了业务需求的开发的模式。 : C* ?3 {5 C9 ]* L7 q, V4 i" r4 d8 M; P) H' n* U: x8 B
1)从设计的角度看,现在的设计首先考虑的整体的设计规范,然后才是个性化需求的表达,从设计的输出物上看,不再是基于数值的标注,而是基于协作语言的标注,对于最终的效果,设计在设计开发阶段就可以有明确的感知,不再需要逐个元素和开发细调,解放了人力。9 j0 i0 k7 O, | L$ d# g
; I8 Q* a% \- C; O% r, M) V, p2)从开发的角度看,开发只需要关注组件的个性化需求实现,而可以复用大部分代码。组件开发上,有公共组件库提供从属性到布局多个维护的标准化实现,而且由于在框架层面的隔离,所有的布局和大部分的卡片都是可以复用的,UI 的复用可以使产品需求的实现只需要关心产品的业务逻辑实现。而且组件是自我独立的,和外部容器之间没有直接引用,所以可以在任何环境下正常工作。经过一定时间的积累和沉淀,我们将会有支持大部分 UI 的布局卡片库。而对于能力的调用我们也提供了标准化的调用接口,开发同学不再需要关注最终具体的实现,只需要关注接口本身可以提供的能力即可。9 i F4 }& }9 x' h
8 z* ], r6 c8 ~ T3)对于产品和运营,统一的配置平台,组件产品全站拉通,都给了他们更低的成本和更好的收益,而设计开发效率的提高也增强了产品试错和复制成功经验的能力。 . F8 [- O7 w" H. c# S+ G, ]5 Y1 y9 d T8 H& ?% [5 n3 x: [+ l1 q
4)在实际收益上,渲染标准化之后我们已经积累十余个通用组件,节约了垂类业务的开发人力,研发效率提高了 40%。我们的用户体验优化的项目中,比如异步加载,轻量化等等都通过标准化快速落地到了每一个业务场景,将之前两三个月的落地周期缩短到了两个迭代。再如设计标准化,为暗黑模式的快速完成,提供了技术基础,使之前一个月全员投入的需求在两周之内完成上线。 * F' Q- L8 s$ g- ~; J. y/ F) Z, n" O3 ~1 l0 W' w% ~0 V- j' i2 |
我们的架构设计成果,还在促进着阿里集团其他应用的标准化,比如来疯等独客在接入后,一次开发,可以快速在优酷,来疯,虾米等多个应用投放。 1 T* T1 A. l% C4 E. J+ G8 c- `' s
备注: , U; s7 [ o* @ 6 O7 e1 I; a. n( CPO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应 PO 的一个(或若干个)属性。7 T3 ^7 p: ^4 @- x6 \6 U6 Z
) M: P& Y, F8 I/ G* O1 K* |; B& m4 p4 k. _VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。 9 \! [9 c( o3 H% i, L, ]. w% w0 f- X
DTO(Data Transfer Object):数据传输对象,泛指用于展示层与服务层之间的数据传输对象。 w) m* M7 S. _0 X3 b% h * p1 _3 q) X- r9 S) H5 [( hDO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。 : `% Y. C+ a- m 0 s+ P! e8 B- V5 R5 |0 m作者 | 阿里文娱无线开发专家 涵父 0 v) a; _0 C' _5 I' t" c7 R ) d1 L" {3 B% X: O# J———————————————— 3 ?3 ]8 _- G) s6 \版权声明:本文为CSDN博主「阿里巴巴文娱技术」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 S* r) {. m r; u8 i2 U
原文链接:https://blog.csdn.net/alienttech/article/details/106167060 . T, h. S& r6 p % ^; o8 i4 U) _* e ) F1 d& e* Z! p g+ Y9 p