iOSなアーキテクチャVIPERのススメ
by
hirothings
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
iOS なアー キテクチャVIPER のススメ @hirothings
Slide 2
Slide 2 text
5 分で話すこと 1. なぜプロダクト開発にVIPER を採用したか 2. VIPER とは 3. どうチー ムに共有したか 4. テストについて
Slide 3
Slide 3 text
自己紹介 @hirothings 新卒でラー メン屋勤務 半年で麺場を任される 1 年でラー メン屋店長 色々 あって現在iOS エンジニア Money Forward, Inc. 所属
Slide 4
Slide 4 text
MVC、MVVM アー キテクチャでアプリを作っ て感じた課題 工夫しないと ルー ティングがない デー タの取得・ 加工だけをする層がない 結果、View のロジックとデー タに関するロジックが混在する 依存性をひとまとめに解決する層がない よって実装が属人化する
Slide 5
Slide 5 text
新規でプロジェクトを始めるにあたって 先の課題は仕組みで解決したい 初期リリー スに間に合わせるにはそこまで時間がない 前提: デー タバインディングを多用するほどのインタラクティブな アプリではない( プロパティ監視などの実装で担保できると判断)
Slide 6
Slide 6 text
もう少しかっちりしたアー キテクチャが欲しい スピー ドも担保したい
Slide 7
Slide 7 text
VIPER 出典: https://cheesecakelabs.com/blog/ios‑project‑architecture‑using‑ viper/
Slide 8
Slide 8 text
VIPER とは 単一責任の原則をもとに作られたアー キテクチャ 各レイヤー はInterface(Protocol) にのみ依存している iOS の現場で生まれたアー キテクチャ "VIPER is an application of Clean Architecture to iOS apps." 出典: https://www.objc.io/issues/13‑architecture/viper/
Slide 9
Slide 9 text
VIPER のレイヤー View Interactor Presenter Entity Router 各レイヤー の頭文字の組み合わせで VIPER
Slide 10
Slide 10 text
各レイヤー の説明 Entity バリュー オブジェクト
Slide 11
Slide 11 text
各レイヤー の説明 Interactor Presenter のイベントに応じてユー スケー スごとにデー タの取得、 加 工をする層 バリュー オブジェクト(Entity) を操作するビジネスロジックが含まれ る View からは完全に分離している
Slide 12
Slide 12 text
各レイヤー の説明 Presenter View に対するビジネスロジックを持つ層 View とRouter, Interactor の橋渡し的存在 View から受け取ったイベントをもとにInteractor にデー タを要求す る View から受け取ったイベントをもとにRouter に画面遷移を依頼する Interactor から受け取ったデー タをView に渡す
Slide 13
Slide 13 text
各レイヤー の説明 View Presenter の言われたとおりに画面にデー タを表示する Presenter にユー ザー のイベントを通知する
Slide 14
Slide 14 text
各レイヤー の説明 Router 画面遷移を管理する 各レイヤー のインスタンスを生成し、 画面を描画する( 依存性をひと まとめに解決する層はここ)
Slide 15
Slide 15 text
※ 各レイヤー はInterface で繋がっていて、 別のレイヤー の具体的な 実装は知らない
Slide 16
Slide 16 text
今までの設計に抱いた課題 VIPER を採用すると ルー ティングがない Router が担保してくれる View のロジックとデー タに 関するロジックが混在 Presenter, Interactor で明確に分離され ている 依存性をひとまとめに解決 する層がない Router がインスタンスを生成し依存性 をまとめる役割を担っている 属人化する レイヤー が明確なため属人化しづらい
Slide 17
Slide 17 text
求めていたものが揃っている感☺ iOS の現場で生まれたアー キテクチャだからか あ、 なんかしっくりくると思った
Slide 18
Slide 18 text
チー ムに共有したい..
Slide 19
Slide 19 text
サンプルアプリを作った よさそう → 自信を持って勧められる状態にするため シンプルなアプリで実装の流れをチー ムに知ってもらう
Slide 20
Slide 20 text
TL が見られる簡単なTwitter クライアント
Slide 21
Slide 21 text
実装内容 ログイン状態に応じたルー ティング 追加ロー ディング エラー 処理 単体テスト コー ドジェネレー タ 結果: 自信を持って勧めたいと思った。 チー ムでも好評だった
Slide 22
Slide 22 text
各レイヤー はInterface で繋がっていて、 実態が何をやっているかは知らない = テストが簡単
Slide 23
Slide 23 text
テスト Stub とSpy を使ったユニットテストを採用 入力 ( デー タ取得) Protocol を使ってスタブに差し替える 出力 (View) Protocol を使ってスパイに差し替える メリット テストしたいこと以外のレイヤー をダミー にすることでテスト したいレイヤー 以外の実装に振り回されずに済む 参考: Speaker Deck: 単体テストのハジメ @yokoyas000
Slide 24
Slide 24 text
例) タイムライン表示のPresenter のテスト
Slide 25
Slide 25 text
手順1. モックを作る テストケー スごとのダミー デー タを用意する
Slide 26
Slide 26 text
手順2. モックを入力するスタブを作る Interactor の代わりに、 指定されたモックを返すだけのスタブを作成
Slide 27
Slide 27 text
手順3. 結果を出力するスパイを作る View の代わりに、 Presenter の結果を出力するだけのスパイを作成
Slide 28
Slide 28 text
手順4. Presenter のテストを書く
Slide 29
Slide 29 text
VIPER x UnitTest 各レイヤー がInterface だけで繋がっているため簡単にダミー に差し 替えられた Presenter 以外のレイヤー の実装に悩まされず済んだ (View 層のUIKit のライフサイクルなど) 単一責任なためレイヤー ごとのテストもしやすい
Slide 30
Slide 30 text
レイヤー が多い= ボイラー プレー トが多い問題 Kuri などのコー ドジェネレー タを使って解決 https://github.com/bannzai/Kuri テンプレを用意したら画面ごとに必要なファイルを吐き出してくれ る
Slide 31
Slide 31 text
VIPER で実装してみた感想 どのレイヤー が何をすべきか理解しやすい 欲しいレイヤー が揃っていてiOS 開発してて、 しっくりくる Interface で各レイヤー が依存しているため簡単にモックに差し替え られる UI ロジックとビジネスロジックが分離しているのでテストがし やすい
Slide 32
Slide 32 text
まとめ 前提: 現場によって必要なアー キテクチャは違う ただiOS やってる人には誰にもわかりやすく 取り入れやすいアー キテクチャだと思った
Slide 33
Slide 33 text
サンプルアプリを公開しました https://github.com/hirothings/VIPERTwitterClient
Slide 34
Slide 34 text
参考記事 iOS Project Architecture: Using VIPER Architecting iOS Apps with VIPER
Slide 35
Slide 35 text
ご静聴ありがとうございました