統一架構——優酷主客的標準化開發之路

一、超級 APP 的標準化

在技術領域,標準化有很多很好的實踐案例。比如服務端容器的出現,應用的構建、分發和交付得以在容器層面上實現標準化,提升了業務創新的效率。

那麼一個客戶端應用的標準化是什麼呢?一個業務需求通常可以拆解爲功能需求,設計需求,體驗需求,數據需求和運營需求,而

每一種需求都對應着一類開發工作。

通過對每一類開發工作進行分析研究,我們得出了一個結論,客戶端開發的標準化是運行時環境一致,視覺效果統一,遵守相同的數據協議,用相同的方法搭建,投放和獲得用戶反饋的標準化。具體抓手則是以渲染架構標準化爲核心的一系列標準化設計和工作。

二、優酷的標準化實踐

1.渲染架構標準化

通常一個應用是由一個一個頁面組成的,而頁面是由什麼組成的呢?我

們可以大致分爲三個部分:數據,組件和服務。

數據模型是業務模型的抽象化產物,是頁面的裏,它的結構來源於業務的需要,影響着組件的實現。數據從媒資,算法等生產源頭通過 CMS(內容管理系統)匯聚而來,通過網絡以字節流傳輸到客戶端,客戶端下載,解析,轉換成對象,或統一保存,或組織分發給每一個顯示單元,從而完成其從生產到消費漫漫征途。

數據需要貼合業務,如果有一個環節的格式定義出現差異,最終的結果可能就會大不相同,而刷洗數據,轉化格式又會帶來效率上的降低。而對統一架構和標準化組件來說,我們又希望數據的格式和字段是一致的。如何來解決這一對矛盾獲得最優解呢?

我們從兩個方向進行了嘗試,一個是在頁面搭建方向上,推進了服務端的數據協議的標準化,之前服務端的數據模型大致都是 page-module-component-item 的多層嵌套結構,它對應了運營同學在搭建頁面時,從整體到局部到細節的設計思路和操作行爲。我們的標準化思路就是虛化節點定義,明確節點結構。虛化節點定義的意思,我們不再以 page,module 等有具體意思和層級關係的名稱作爲節點 tag,而是統一爲 Node。這樣原本有層級關係的結構,就變成了可以任意嵌套的結構。而對於 Node,明確其內部爲 level,data[],style[]和 subNodes[]等含義明確的標準化結構。而在組件渲染方向上,我們將數據結構演化抽象爲從 PO-DTO-DO-VO【備註】的過程。而我們在 VO 這一層去抹平之前的協議差異。

1)組件是頁面的表,直接響應用戶體驗。組件的核心設計原則是組件在不同頁面上的複用,爲此我們將組件的內部實現分解爲 Model,View 和 Presenter 三個部分,各部分之前只以 Contract 約束接口定義。這樣三類模塊都可以進行不同實現的組合和替換,我們剛纔說的在 VO 抹平數據協議差異,就是通過配置不同的 Model 完成的。此外,我們在組件的佈局管理使用了 vLayout 的佈局混排能力,在配置上通過文件配置進行佈局樣式上配置和組件 MVP 的搭配,還提供了組件間的通信能力。這些標準化接口的提供,統一了組件的使用環境,大大降低了組件的 UI 開發的難度。

2)服務是頁面的神,有了服務頁面纔是活的。對於服務我們抽象爲域內服務和域外服務,域內服務指的是頁面範圍的視覺動作,比如組件的插入,刪除,刷新,加載更多等,這部分能力我們在數據域對象提供了內置的方法,而域外服務則是指對業務中間件和應用基礎能力的調用,對於這部分調用,我們在服務能力標準化再介紹。

在渲染架構標準化的設計中,我們強調了解耦,而這對配置化的實現也帶來了便利。通過對頁面佈局能力的拆解,對組件 MVP 的結構設計,渲染標準化架構把一個組件拆解成了這個組件的容器,容器的 adapter,組件的 MVP 部件,組件交互需要的領域能力,組件交互需要的基礎服務等獨立部分,可以自由配置組合。在組件承載的業務上,我們也通過代理來進行配置,代理可以拿到頁面的上下文,監聽業務的消息進行響應,不同的使用場景都遵循着相同規則。

  1. 設計體系標準化

客戶端用戶界面一致性是設計體系標準化需要關注的核心問題,保證一致性和體驗品質,並實現設計開發的工作提效,是“設計語言標準化管理體系”的建設的核心訴求。爲此,我們聯合設計一起,從零創立了優酷自己的設計體系。我們爲設計體系設定了核心目標:建立設計語言的標準化管理體系,改變設計與開發生產模式,實現設計與開發的品質和效率提升。

爲了完成這個目標,我們進行了很多工作。設計同學對全站的現有設計進行了盤點,統一設計和技術對界面元素的認知體系,定義了設計規範。開發同學建立了標準化組件庫,以視覺規範爲基礎,把設計側的規範文檔及組件庫,通過一種協作語言形成設計與技術的映射關係,實現客戶端設計組件與技術組件的統一拉通,沉澱成統一的 SDK 共同維護。而協作語言的確立,標誌着標準化的工作的具象,從根本改變了之前設計開發的工作流程。

以往開發實現過程中,研發代碼中會寫原始屬性值,而這個寫的過程本身就是孤立的,非標準化的,而現在研發以引入 Design Token 的方式,把視覺樣式的代碼進行統一管理,形成統一的研發組件庫,各業務線可以直接調用,收攏了散落各處的代碼。Token 最終會對應什麼樣的呈現,完全基於標準規範。而通過對規範的調整,可以對應用整套設計進行體系化的調整。

  1. 服務能力標準化

渲染架構的標準化有一個重要的設計就是將服務和渲染分離開。

不同業務模塊,一般都會依賴不同的中間件,按照之前的服務和渲染耦合的設計,相同的服務能力在不同業務模塊間往往實現多次,這既增加了學習成本,形成技術壁壘,也使代碼結構脆弱和臃腫。而且服務的接入成本高,迭代成本也高,冗餘的代碼既影響了編譯速度,更影響了啓動速度。

爲此,我們設計了標準化的服務接口和服務中間層,每個模塊都通過調用服務中間層的標準化接口,來獲得或者觸發服務。這既使渲染和服務解耦,也完成了中間件之間的接耦,形成了高內聚低耦合的架構層次。

1)未標準化之前。

2)標準化之後。

這是標準化前後的對比圖,從圖上我們可以看到,標準化之後,上層業務依賴的不再是具有某一套服務接口和實現,而是可以根據實際的情況,靈活配置服務。基礎的服務和業務中間件的變更成本也降到了最低。

三、標準化後的成果

完成了這些標準化工作之後,目前優酷的整體架構大致是這樣的。

通過一系列的標準化工作,實際上改變了業務需求的開發的模式。

1)從設計的角度看,現在的設計首先考慮的整體的設計規範,然後纔是個性化需求的表達,從設計的輸出物上看,不再是基於數值的標註,而是基於協作語言的標註,對於最終的效果,設計在設計開發階段就可以有明確的感知,不再需要逐個元素和開發細調,解放了人力。

2)從開發的角度看,開發只需要關注組件的個性化需求實現,而可以複用大部分代碼。組件開發上,有公共組件庫提供從屬性到佈局多個維護的標準化實現,而且由於在框架層面的隔離,所有的佈局和大部分的卡片都是可以複用的,UI 的複用可以使產品需求的實現只需要關心產品的業務邏輯實現。而且組件是自我獨立的,和外部容器之間沒有直接引用,所以可以在任何環境下正常工作。經過一定時間的積累和沉澱,我們將會有支持大部分 UI 的佈局卡片庫。而對於能力的調用我們也提供了標準化的調用接口,開發同學不再需要關注最終具體的實現,只需要關注接口本身可以提供的能力即可。

3)對於產品和運營,統一的配置平臺,組件產品全站拉通,都給了他們更低的成本和更好的收益,而設計開發效率的提高也增強了產品試錯和複製成功經驗的能力。

4)在實際收益上,渲染標準化之後我們已經積累十餘個通用組件,節約了垂類業務的開發人力,研發效率提高了 40%。我們的用戶體驗優化的項目中,比如異步加載,輕量化等等都通過標準化快速落地到了每一個業務場景,將之前兩三個月的落地週期縮短到了兩個迭代。再如設計標準化,爲暗黑模式的快速完成,提供了技術基礎,使之前一個月全員投入的需求在兩週之內完成上線。

我們的架構設計成果,還在促進着阿里集團其他應用的標準化,比如來瘋等獨客在接入後,一次開發,可以快速在優酷,來瘋,蝦米等多個應用投放。

備註

PO(Persistent Object):持久化對象,它跟持久層(通常是關係型數據庫)的數據結構形成一一對應的映射關係,如果持久層是關係型數據庫,那麼,數據表中的每個字段(或若干個)就對應 PO 的一個(或若干個)屬性。

VO(View Object):視圖對象,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。

DTO(Data Transfer Object):數據傳輸對象,泛指用於展示層與服務層之間的數據傳輸對象。

DO(Domain Object):領域對象,就是從現實世界中抽象出來的有形或無形的業務實體。

作者 | 阿里文娛無線開發專家 涵父

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章