まだ情報の少ない RIBs 紹介するシリーズです。(予定)
RIBs
- 第1章 RIBsとは
- 第2章 各コンポーネントの役割と RIB 同士の接続( Attach / Detach )(予定)
- 第3章 Stream を使った RIB 同士のコミュニケーション方法(予定)
- 第4章 WorkFlow で見通し良く URLScheme / UniversalLink を実装(予定)
- 第5章 RIB ツリーの設計方法 (予定)
第1章
この記事では、RIBs の概要を説明します。
README.md と Wiki の内容を抜粋した記事になります。
完全な和訳ではないことと私自身が 100% 理解仕切っているわけでは無いため、理解が間違っている箇所がある可能性がります。
記事を読んで少しでも興味が湧いた方は、本家のドキュメントをご覧になってください。
RIBs とは
Uber が開発したアーキテクチャで、フレームワークとして提供されています。
Router, Interactor, Builder というコンポーネントの接頭辞を取ったものです。
多数のエンジニアチームやネストされた状態を持つアプリ向けに設計されています。
初回コミットは 2017/10/4 で、比較的新しいアーキテクチャです。
We re-wrote the Uber application in 4 months with 200 engineers.
Uberは200名のエンジニアで4ヶ月掛けて書き直したようです。
特徴
スケーラブル
Uber では502名のモバイルエンジニア、650 RIBs まであり、1クラスは300行以内。 (資料)
クロスプラットフォームコラボレーション
アプリのビジネスロジックのほとんどは、 iOS も Android も似ています。 RIB を使用することで、共同設計されたアーキテクチャを共有できます。
またビジネスロジックのクロスレビューが可能とUberは申しております
グローバルな状態を最小限にする
グローバル変数やシングルトンオブジェクト等の状態変化は予測できず、予期せぬ動作を引き起こす可能性が高く、修正時の影響範囲を完全に把握することは困難です。 RIBs は深い階層内に状態をカプセル化し、グローバルな状態で起こり得る問題を極力回避できます。
テストが容易
クラスは単体テストが容易である必要があります。
RIB は 責任範囲が明確で親RIBと子RIBはインターフェースに依存した形でロジックは切り離されています。
その結果、テストが容易になります。
以下参考
Interface | Implementation |
---|---|
Buildable | Builder |
Routing | Router |
Interactable / PresentableListener | Interactor |
ViewControllable / Presentable | ViewController |
オープンクローズドの原則
開発者は既存コードをほとんど変更せずに新機能を追加できます。
具体的に言うと、親RIBに子RIB(新機能)を追加する場合、子RIBの依存関係の解決とAttach/Detach処理、子RIBのListenerに準拠することで追加が可能です。
ビジネスロジックを中心に構造化
ビジネスロジックと画面構造は厳密に合わせる必要はありません。
画面階層はRIB階層よりも浅いことがあります。
1つのRIBが、異なる場所に表示されている複数のViewの外観を制御できます。
(*個人的にまだしっくり来ていない箇所です)
明示的
複数RIBにまたがる依存は、ReactiveX を使用して表現され、RIB毎に DI を使用することで、依存関係が明確になりコンパイル時に保証されます。
不変量の作成も促されます。
開発用のツール
- 大規模チームの生産性向上のためのツールが付属 (一部Androidのみ)
- コード生成テンプレート
- メモリリーク検出 ( Attach / Detach )
- 静的解析 ( Android のみ)
RIBs と MV* / VIPER の違いは何か
MVC、MVP、MVI、MVVM、VIPER はアーキテクチャパターンです。
RIBs はフレームワークです。
違いは以下の通り
- ビジネスロジックに主眼を置く
- RIB は View を持つ必要は必ずしもありません。アプリケーションの階層は画面ではなくビジネスロジックによって決まります。
- 独立したビジネスロジックとビューツリー
- RIB は 画面とビジネスロジックを切り離します。その結果、深いビジネスロジックツリーを持ち、浅いビュー階層を保持したまま、レイアウト・アニメーション・トランジションを容易にします。
以下については他の MV* / VIPER でも実装することが出来ますが、他にもいくつか特徴があります。
- クロスプラットフォーム
- iOS と Android で RIBs を採用することが出来ます。
- 大規模なアプリやチームで導入を容易にするツールが付属します。
- コードテンプレート
- 静的コード解析のための IDE プラグイン (まだ無いかも?)
- DI / Rx を使って依存関係を解決
- 各 RIB は依存関係を定義しており、親子関係のある RIB の場合、子の依存は親から提供されます。
公式ドキュメント
GitHub リポジトリの Wiki に詳細な説明が書かれています。
この記事を読んで少しでも興味が湧いた方は、ぜひ読んで見ましょう。
RIBs を採用したアプリ
- JapanTaxi iOS
- Uber iOS/Android
- Tada
- ...情報収集中
RIBs 開発を支援するOSS
-
RIBsTreeMaker
https://github.com/imairi/RIBsTreeMaker
RIBsツリーを静的に生成してくれて、UMLツールで表示させることができます。
RIBs同士が繋がるパターンを網羅的に出力してくれます。 -
RIBsTreeViewer
https://github.com/srea/RIBsTreeViewerClient
アプリ起動中のRIBsツリーをリアルタイムに可視化します。
参考リンク
Slack
こちらで招待を受けることが出来ます。
https://uber-ribs-invite-automation.herokuapp.com
Uber Blog
Slideshare
- Uber's new mobile architecture
Speaker Deck
- Hot Off The Grill: RIBs
Vimeo
- Building apps at scale - Pavel Mazurin & Victor Pena (2018/10/02)
Youtube
- Mobile Architecture at Scale - Gergley Orosz
- RIBs - Uber's new mobile architecture that scales to hundreds of engineers by Tuomas Artman
- [Uber Mobility] RIB (Router Interactor Builder) - Yi Wang
- droidcon SF 2017 - Hot Off the Open-Source Grill: RIBs, Scalable Multiplatform App Architecture
- Uber Mobility: RIB (Router Interactor Builder)
(次回は、各コンポーネントの役割について、私 or 仲間が書く予定です)
追記 (2020/01/14)
書いた当時はシリーズ化を目指していましたが、ご覧の通りです
RIBsTreeViewerという、アプリ起動中のRIBツリー構造をブラウザから可視化できるツールを公開しました。
様々なケースで使えるのですが、チーム開発に追いて新規メンバーの内部構造理解速度を向上させることが出来ます。