iOS 工程

[iOS 架構 #10] Uber RIBs:以商業邏輯拆分 App

RIBs 不是以畫面,而是以商業邏輯單位拆分 App。本篇整理無畫面元件存在的前提、只適合超大型組織的原因,以及它和 VIPER 的差異。

閱讀 4 分鐘
[iOS 架構 #10] Uber RIBs:以商業邏輯拆分 App 封面圖

在 VIPER(View·Interactor·Presenter·Entity·Router)篇中,我曾用一段話帶過「Uber 受到 VIPER 啟發而打造的 RIBs」,這次就來完整介紹。在韓國,RIBs 也因 Toss 採用而廣為人知。

理解 RIBs 的關鍵只有一個。到目前為止介紹的所有架構(MVC·MVVM·VIPER·ReactorKit)都以畫面作為基本單位。RIBs 捨棄了這個前提,改以商業邏輯為單位拆分 App。


無畫面元件的存在

RIBs 是 Router·Interactor·Builder 的縮寫。這三者是每個元件(RIB)的必要組成,只有在需要時才會加入 Presenter 和 View。

  • Interactor:商業邏輯的核心,也是 RIB 的大腦。
  • Router:透過 attach 和 detach 子 RIB 來管理樹狀結構。
  • Builder:組裝一個 RIB,並注入相依性。
  • Presenter·View:選用項目,只存在於需要畫面的 RIB。

「View 是選用項目」這點至關重要。以叫車 App 的「乘車中」狀態為例,它涵蓋地圖畫面、司機資訊卡和付款準備邏輯,但本身不是某一個特定畫面。在 RIBs 中,可以把它做成無畫面的 viewless RIB,再將有畫面的子 RIB 掛在其下。

整個 App 會成為 RIB 的樹狀結構。登入狀態、乘車狀態等App 的狀態變化,就是樹狀結構的變化。登出時,LoggedIn RIB 會從樹中完整移除,其下的畫面和邏輯也一併消失。狀態管理也就是樹狀結構管理。

說明 RIBs 樹狀結構,以及無畫面 RIB 與擁有 View 的 RIB 差異的範例圖
登入、乘車等 App 狀態,就是樹狀結構的形狀

為什麼只有超大型組織會使用?

RIBs 從一開始的設計目標就是「數百人共同開發一個 App」。Uber App 有數十個團隊同時提交程式碼,只靠畫面單位的分離無法建立團隊邊界,因為同一個畫面會混入多個團隊的邏輯。

以 RIB 為單位拆分後,每個團隊都能擁有自己的 RIB 子樹。Builder 強制規定相依性注入的位置,因此根本無法碰觸其他團隊 RIB 的內部。這是在架構層級實現模組化系列提到的「強制邊界」。

Toss 導入 RIBs 的原因也相同。在一個 App 包含數十種金融服務的超級 App 結構中,讓每項服務成為一個 RIB 子樹後,掛接和移除都會很明確。

反過來說,這些優點在小型團隊中都會變成成本。

第一,樣板程式碼比 VIPER 還多。一個 RIB 基本上會產生四到五個檔案,因此 Uber 也提供程式碼產生範本。

第二,學習曲線很陡。團隊必須學會樹狀結構設計、attach/detach 時機,以及依範圍管理的相依性注入,才能建立共同理解。

第三,它和以畫面為中心的思考方式不一致。規格通常以畫面為單位,而 RIBs 以狀態拆分,因此在設計階段需要進行轉換。

它和 VIPER 有什麼不同?

只看組成元件名稱,可能會以為它是 VIPER 的變體,但兩者的差異是根本性的。

VIPER RIBs
基本單位 畫面 商業邏輯
無畫面元件 不可能 viewless RIB
導覽 Router 負責畫面切換 Router 負責樹狀結構的 attach/detach
目標 分離單一畫面的責任 分離組織單位的程式碼所有權

VIPER 的 Router 負責「如何前往下一個畫面」,RIBs 的 Router 則負責「在目前的 App 狀態下,哪些邏輯元件應該存活」。名稱相同,問題不同。

說明 RIBs 團隊別程式碼所有權,以及 TEAM A、B、C 子樹拆分的插圖
讓每個團隊擁有自己的子樹,才是 RIBs 真正的目的

總結

  • RIBs 是 Uber 的架構,將 App 以商業邏輯單位拆成樹狀結構,而不是以畫面拆分。
  • RIB 可以沒有畫面,並以樹狀結構的 attach/detach 表現 App 狀態變化。
  • 它的目標是團隊別的程式碼所有權與強制邊界,因此在數百人規模的組織中最能發揮價值。Uber 和 Toss 是代表案例。
  • 對小型團隊而言,樣板程式碼和學習曲線會壓過優點。選擇標準就如第 8 篇的選擇指南所述,團隊規模是大部分答案。

至此,iOS 架構系列中只提過但尚未深入介紹的部分也全部補齊了。從 MVC 到 RIBs,請記住所有架構最終都是對同一個問題「邏輯應該放在哪裡」提出的不同答案。

延伸閱讀

iOS 架構系列