iOSエンジニアリング

[iOSアーキテクチャ #10] Uber RIBs:ビジネスロジック単位でアプリを分割する

RIBsは画面ではなくビジネスロジック単位でアプリを分割します。画面を持たないコンポーネントという前提、超大規模組織でのみ使われる理由、VIPERとの違いを整理します。

読了 5 分
[iOSアーキテクチャ #10] Uber RIBs:ビジネスロジック単位でアプリを分割するのカバー画像

VIPER(View·Interactor·Presenter·Entity·Router)の回で「UberがVIPERに着想を得て作ったRIBs」と一段落で触れましたが、今回は詳しく扱います。韓国ではTossが採用したアーキテクチャとしてもよく知られています。

RIBsを理解する鍵は一つです。これまで扱ったすべてのアーキテクチャ(MVC·MVVM·VIPER·ReactorKit)は、基本単位として画面を使っていました。RIBsはこの前提を捨てます。画面ではなくビジネスロジック単位でアプリを分割します。


画面を持たないコンポーネントが存在する

RIBsはRouter·Interactor·Builderの略です。この3つが一つのコンポーネント(RIB)に必須で、必要な場合だけPresenterとViewが加わります。

  • Interactor:ビジネスロジックの本体。RIBの頭脳です。
  • Router:子RIBをattach・detachし、ツリーを管理します。
  • Builder:RIBを組み立て、依存性を注入します。
  • Presenter·View:オプションです。画面が必要なRIBにだけ存在します。

「Viewがオプション」である点が決定的です。たとえば配車アプリの「乗車中」状態を考えてみましょう。この状態は地図画面、運転手情報カード、決済準備ロジックを含みますが、それ自体は一つの画面ではありません。RIBsではこれを画面のないviewless RIBにし、その下に画面を持つ子RIBを接続します。

アプリ全体がRIBのツリーになります。ログイン状態や乗車状態などのアプリの状態変化が、そのままツリーの形の変化です。ログアウトするとLoggedIn RIBがツリーから丸ごと外れ、その下の画面とロジックも消えます。状態管理はツリー管理そのものです。

RIBsのツリー構造と、viewless RIBおよびViewを持つRIBの違いを示す図
ログインや乗車などのアプリ状態がツリーの形になる

なぜ超大規模組織だけが使うのか

RIBsの設計目標は、最初から「数百人で一つのアプリを作ること」でした。Uberのアプリには数十のチームが同時にコードを追加するため、画面単位の分割ではチームの境界を作れませんでした。一つの画面に複数チームのロジックが混在するからです。

RIB単位で分割すると、各チームが自分のRIBサブツリーを所有できます。Builderが依存性注入のポイントを強制するため、他チームのRIB内部に触れる方法自体がありません。モジュール化シリーズで扱った「境界の強制」をアーキテクチャレベルで実現します。

TossがRIBsを導入した理由も同じです。一つのアプリに数十の金融サービスを含むスーパーアプリ構造では、各サービスを一つのRIBサブツリーにすると、接続と切り離しが明確になります。

逆に、この利点は小規模チームではすべてコストになります。

第一に、ボイラープレートがVIPERより多くなります。一つのRIBに基本的に4〜5個のファイルが生まれます。Uberもこのためコード生成テンプレートを提供しています。

第二に、学習曲線が急です。ツリー設計、attach/detachのタイミング、スコープごとの依存性注入まで学び、チーム全体で同じイメージを共有する必要があります。

第三に、画面中心の考え方と合いません。企画書は通常画面単位で作られますが、RIBsは状態単位で分割するため、設計段階で翻訳が必要です。

VIPERとは何が違うのか

構成要素の名前だけを見るとVIPERの変形に見えますが、違いは根本的です。

VIPER RIBs
基本単位 画面 ビジネスロジック
画面のないコンポーネント 不可能 viewless RIB
ナビゲーション Routerが画面遷移を行う Routerがツリーをattach・detachする
目標 一つの画面の責務を分離する 組織単位でコードの所有権を分離する

VIPERのRouterは「次の画面へどう遷移するか」を担当します。一方、RIBsのRouterは「現在のアプリ状態で、どのロジックコンポーネントが生きているべきか」を担当します。同じ名前でも、問いが違います。

RIBsにおけるチーム別コード所有権と、TEAM A・B・Cのサブツリー分割を示す図
チームごとに自分のサブツリーを所有することが、RIBsの本当の目的です

まとめ

  • RIBsは、画面ではなくビジネスロジック単位でアプリをツリー構造に分割するUberのアーキテクチャです。
  • 画面のないRIBが許容され、アプリ状態の変化をツリーのattach・detachで表現します。
  • チームごとのコード所有権と境界の強制が目的なので、数百人規模の組織で真価を発揮します。代表例はUberとTossです。
  • 小規模チームでは、ボイラープレートと学習コストが利点を上回ります。選択基準は第8回の選択ガイドで扱ったとおりです。答えの大半はチーム規模にあります。

これで、iOSアーキテクチャシリーズで触れるだけだった要素まで埋まりました。MVCからRIBsまで、すべてのアーキテクチャは結局「ロジックをどこに置くか」という同じ問いへの、異なる答えだと覚えておいてください。

あわせて読みたい

iOSアーキテクチャシリーズ