レガシーなプロダクトからドメイン層を再設計する / iOSDC_takahashi_ishii

 

Transcript

  1. (2018.10-) 高橋陽太郎 • 株式会社リクルート • Engineering Manager
    1. 自己紹介 石井 潤 • 株式会社リクルート( 2018.04-) • iOS/Android App Developer

  1. る Model APIやDBアクセス レイヤリングを適切にする ことでFat Viewから脱却 したい。 なぜか依存している DBアクセス用のモデル を生成してたりする
    1. これまでのあらすじ:混乱に秩序をもたらすリアーキテクチャ奮闘中 での出来事 View 肥大化。 ロジックやデータが モリモリに入ってい る Presenter ほぼログ送信のロ ジックしかなく薄すぎ

  1. て肥大化。 UseCase ほぼRepositoryの ラッパー Repository ほぼDataAccessの ラッパー DataAccess APIやDBアクセ ス DomainModel
    1. そしてFat Presenterが出来上がった View 表示とイベント通知 (簡素化に成功) Presenter 画面表示のための データやフラグ、 ビジネスロジック。 大量の状態を持っ

  1. UseCase ほぼRepositoryの ラッパー Repository ほぼDataAccessの ラッパー DataAccess APIやDBアクセ ス DomainModel 【疑問】 状態を置くレイヤーが適切ではない のでは? Presenter 画面表示のための データやフラグ、 ビジネスロジック。 大量の状態を持っ て肥大化。
    1. これがやりたかったことではなかったはずなのに、どうしてこうなったんだろう? View 表示とイベント通知 (簡素化に成功) Presenter 画面表示のための データやフラグ、 ビジネスロジック。 大量の状態を持っ て肥大化。

    1. twadaさん「どのレイヤーがどんな責務を持つかという議論の前に (多くのエンジニアが陥りがちな問 題)、ドメインがどうなっているかを知ることが重要だよ」 「多くのエンジニアが陥りがちな問題ですが、 どのレイヤーがどんな責務を持つべきか という議論の前に、ドメインがどうなっているかを知ることが重要 です」

    1. 自分たちがモデリングしたものを再びtwadaさんにみてもらうと 既存の実装で扱われているデータのモデリングになってしまっていて、 UI/API/DBの実 装の影響を強く受けてしまっていますね。 本来、タウンワークアプリの本質って何でしょうね? 何の価値を提供しているんで しょう? 例えば、「求人情報」が「既読ステー タス」を持っているのって何かおかし くない?

  1. ◦ 別のUIや実行基盤でも考えてみて同じように価値を提供できるか確認する • これらを意識してモデリングをしてみたら、レイヤリングに注力していた最初期から はアプリの捉え方、認識の仕方がまるっきり変わっていた。 ↑スライドの途中ですが一番伝えたかったことです。
    1. ここまでの気づき • 我々エンジニアはすぐに実装やレイヤリングに目がいってしまうが、それではドメイ ンモデルには辿り着かない。 • 実装から離れて、0ベースでドメインのことを考える。 ◦ まずはアプリの本質、どんな価値をユーザーに提供するかを考える ◦ その際、UI/DB/APIなど実装上の制約は考えない

    1. TIP1: ドメインモデルには情報ではなく事実を持たせる 「掲載終了期限」には2通りの表現がある 「yyyy/mm/dd」「あと〜日で終了」 事実を目的に沿って加工したものが情報 そのため、ドメインには事実を持っていた方が変更に強い https://speakerdeck.com/twada/test-driven-architecture-aws-dev-day-tokyo-2018?slide=90(大元は『SQLアンチパターン』)

  1. 【仕様③】JR中央本線 の「新宿駅」を選択する と、別路線の新宿駅も 選択状態になる。 【仕様④】 ユーザーには選択した 都道府県+選択した駅 名で表示する
    1. TIP2: ドメインモデルは現実よりも複雑で豊かなり タウンワークにおける検索時の駅選択のモデリング 【仕様①】 基本的にはユーザーが 選択している都道府県 の駅が選択できる 【仕様②】 同一路線上の他の都道 府県の駅が選択できる

  1. • でも、我々アプリの本質は「ユーザーと求人とのインタラクション」を実現すること。それ にまつわるドメインモデリングはアプリでも必要だった。 ◦ 例えば閲覧履歴や検索条件など、ユーザーと求人の関係を促進するためのデータはモデルにする価 値がある(右図)
    1. TIP3: アプリの中のドメインモデリング • サーバーでモデリングを頑張りそれを表示するだけなら、アプリのモデリングは必要な い? ◦ 確かにそういうデータも存在する ◦ 例えば求人詳細の給与や時間を立体的なモデルにしてもうまみがない (左図)

    1. 書いたものを評価するときの三要素 1. 【理解容易性】コンテキストを共有していない人(未来のチームメンバー)も理解できる か 2. 【変更容易性】影響範囲を小さくできているか 3. 【テスト容易性】テストの書きやすさ

  1. ◦ インターフェースに変更があると、具象クラス全てに影響が出てしまうため
    1. 変更容易性 • enumのケースやif文、ダウンキャストが増えていくのはよくない兆候(具象を直接 扱っている) ◦ デザインパターンの出番 • 利用者はインターフェースのみを扱う • インターフェースは極力シンプルにして、具象クラスに多くを任せる

  1. 内部状態に強く依存していないか、同じインプットに対して同じアウトプットを返すか ◦ インスタンスを生成する時に長大なセットアップを必要としていないか≒サイズは適切か
    1. テスト容易性 • まずテストが書ける状態かでいろいろ気付ける ◦ 実際にテストを書こうとして不足しているユースケースに気がついた • その上で、テストを書こうとしてみるといろいろと気づきがある、例えば ◦ 疎結合になっているか≒依存性の注入などがしやすいか ◦

    1. 実際に書いてみて検証する 利用者視点でコードを書いて、使いやすいか、要求を満たせているか確かめる。方法は 複数あり、どちらもメリット・デメリットがある。 また、方法によらず、得られたフィードバックを元に改善し続けることがポイント。サービ スが続く限りモデルも進化し続けていく。 1. 実際にViewを作って検証 2. テストコードによって検証

  1. 実際作ってみたことでユースケースに足りない機能があることを発見できた
    1. 実際にViewを作って検証 愚直な方法 󰢃色々時間がかかる • Viewも作る、Presenterも作る、AppDelegateも作る、Factoryも作る… 󰢏やることはわかりやすい なんたって本物だから • 機能を漏らすことはない •

  1. -> 仕様書的にテストを書ける b. 状況 -> データの準備、使い回しがやりやすい
    1. テストコードを書く際に気づいたミニTIP 1. テストはゴール(アサーション)から書くと目的がブレにくい a. 準備に手間がかかると目的を見失ったり、せっかく準備したのだからたくさ ん検証しようとなりがち 2. テストケースの名前の付け方、構造化の仕方、機能が先か、状況が先か a. 機能

  1. ある程度必要 コード量 動かすためのコードが結構必要 👍必要最小限 パターン網羅 データ準備や操作が大変 👍データ準備は必要、あとは実行するだけ 繰り返し検証 大変 👍簡単
    1. Viewを作る vs テストコード 我々の場合は、モデリングが不慣れだったことから、最初にViewを作って利用イメージ を作り、その後テストコードでの検証も取り入れて行った。(twadaさんに導いてもらって だんだん習熟度が上がって行ったのも大きかった) View テストコード 習熟度 👍低くても可能

  1. どちらかで変更があればもう一方にも反映する ▪ 項目→応募入力項目に名前変更 • コードが書けたならモデル(図)はメンテナンスしなくて良い? ◦ それぞれ目的が違う ▪ モデルは全体を俯瞰するために有用 • 全体像、要素の関係を把握しやすい • 仕様変更(新たな仕様)の際に全体の中での位置、既存の要素との関係がすぐわかる モデル コード 全体、俯瞰、 要素の関係 具体、詳細
    1. TIP5:モデルもメンテナンスする? モデルとコードの関係 • モデルとコードは一体 • 行ったり来たりしてフィードバックし合う ◦ モデルだけだと抽象的すぎて要素を見落とすことがあるし、コードだけだと具体的すぎて全体が見えなく なる ◦

  1. た ◦ ドメインには事実を持たせる?情報を持たせる? ◦ ドメインは現実世界のものと対応するべき? ◦ サーバーサイドではなく、アプリでもドメインに注意を払う必要ってあるの? ◦ 作ってみたドメインがしっくりきているかってどうやったらわかるの? ▪ 気づいたらテストコードの書き方も練度が上がっていた ◦ 動作するコードが出来上がったら、モデルもメンテナンスしなければいけないの?
    1. まとめ このセッションで触れた内容 • アーキテクチャに秩序をもたらすべく、リアーキテクチャに取り組んだらFat Presenterになってしまった • レイヤリングに意識を向けていたが、ドメインを掘り起こす作業の中で、アプリケー ションの本質を理解することが重要だと気づいた • モデリングする上でたくさん疑問にぶつかり、それらに自分たちなりの解答を出せ

  1. モデリングする上でたくさん疑問にぶつかり、それらに自分たちなりの解答を出せ た ◦ ドメインには事実を持たせる?情報を持たせる? ◦ ドメインは現実世界のものと対応するべき? ◦ サーバーサイドではなく、アプリでもドメインに注意を払う必要ってあるの? ◦ 作ってみたドメインがしっくりきているかってどうやったらわかるの? ▪ 気づいたらテストコードの書き方も練度が上がっていた ◦ 動作するコードが出来上がったら、モデルもメンテナンスしなければいけないの?
    1. 一番衝撃的だったのは、ドメインに意識を向ける中で我々のアプリ の捉え方がガラッと変わったこと このセッションで触れた内容 • リアーキテクチャに取り組んだらFat Presenterになってしまった • レイヤリングに意識を向けていたが、ドメインを掘り起こす作業の中で、アプリケー ションの本質を理解することが重要だと気づいた •