Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コトダマンサーバーアプリのリアーキテクチャへの挑戦

 コトダマンサーバーアプリのリアーキテクチャへの挑戦

「技術的負債、どうやって解消した?リアーキテクチャ・リファクタ事例から学ぶLunch LT」の登壇資料です
https://findy.connpass.com/event/288877/

Tanaka Kyosuke

July 19, 2023
Tweet

Other Decks in Programming

Transcript

  1. ©MIXI 自己紹介 田中恭友 (Kyosuke Tanaka) デジタルエンターテインメント事業本部 コトダマン事業部 エンジニアグループ マネージャー 2018年4月 株式会社ミクシィ(現MIXI)新卒入社

          モンストドリームカンパニー       サーバーサイドの新規開発・運用 2020年3月 コトダマン事業部に異動       サーバーエンジニアとしてスクラムTで開発・運用 2022年9月 エンジニアマネージャー就任 2
  2. ©MIXI 自己紹介 田中恭友 (Kyosuke Tanaka) デジタルエンターテインメント事業本部 コトダマン事業部 エンジニアグループ マネージャー 2018年4月 株式会社ミクシィ(現MIXI)新卒入社

          モンストドリームカンパニー       サーバーサイドの新規開発・運用 2020年3月 コトダマン事業部に異動       サーバーエンジニアとしてスクラムTで開発・運用 今日のLTはこの頃の話 2022年9月 エンジニアマネージャー就任 3
  3. ©MIXI 10 コトダマンのアーキテクチャ概要  APIサーバー  Java 8(Amazon Corretto) tomcat struts2 DB

    (Amazon Aurora)  チャットサーバー  Java 8(Amazon Corretto) tomcat struts2 その他     運用用途サーバー ゲームクライアント (Unity製) マルチプレイサーバー       monobit engine APIサーバー : ゲーム上の様々な処理を実現するためのAPIを提供(クエスト開始・ガチャ・etc…) 今回のリアーキテクチャ対象
  4. ©MIXI 12 内部品質低下の原因 • ドメインモデルの不在 • 手続き的に書き下されたビジネスロジック • メソッドに渡される大量のプリミティブ型の引数たち •

    ユニットテストの存在しない・後からかけないレガシーコード • 責務の分割されていない巨大メソッド • 状態を持つsingletonクラス(マスタデータや時刻の管理クラス)に 依存せざるを得ない構造 • 制御されていない、縦横無尽の依存関係 • viewに依存したビジネスロジックが汎用性を低下 • ほとんど全てのusecaseが public static な メソッドの集合体として書かれている
  5. ©MIXI 18 リアーキテクチャの狙い • ルールに従って実装しているうちに、 オブジェクト指向らしい設計ができるようになること • ドメインモデルを作成・ビジネスロジックをモデルに集約することを強制し ルールに従った実装をしているうちに学習が進むような設計であること •

    ルールを元にレビューが行えること • 設計の良し悪しを議論するための土台にできること • レビューコストを低下させること • 自動テストを書く文化を成熟させること • ルールに従って実装すればテスタブルな設計になること • 自動テストを必須とする部分・そうでない部分を分けて 少なくともコアなロジックに自動テストを書くことを当たり前にする • TDDが自然と行われる下地を作る
  6. ©MIXI 19 新アーキテクチャ Presentation UseCase DAO Entity Response Request MasterData

    Model Service IRepository Repository Action • オニオンアーキテクチャを参考にシンプルなアーキテクチャに設定 • ビジネスロジックをModel層に集約することを狙う • 依存の方向性を制御し、変動しやすいレイヤにコアロジックが依存しないようにする 依存の方向性
  7. ©MIXI 20 Modelレイヤ  Presentation UseCase DAO Entity Response Request MasterData

    Model Service IRepository Repository Action • ビジネスロジックを受け持つ層 ◦ DDDでいう値オブジェクトやエンティティをこのレイヤに置く ◦ 例: User, Character, Gacha, Quest … etc • Modelレイヤのクラス中の公開メソッドには原則単体テストを必須とする ◦ 自動生成された getter は対象外
  8. ©MIXI 21 Serviceレイヤ  Presentation UseCase DAO Entity Response Request MasterData

    Service IRepository Repository Action • 複数のModelを利用してアプリケーションに必要な機能を実装するレイヤ ◦ 複数のコンテキストで利用される、汎用的かつ複数のModelが関連する処理を置く ◦ 例: ItemService(アイテムの付与) • できる限りModelのみで実装を行うが、綺麗にまとまらない場合にはServiceを使う • 旧実装(Tool)との繋ぎ込みを担う、腐敗防止層として利用されることもある Model
  9. ©MIXI 22 UseCaseレイヤ  Presentation UseCase DAO Entity Response Request MasterData

    Service IRepository Repository Action • アプリケーションの機能を実現するために、処理順序を規定するためのレイヤ ◦ 例: ExchangeItemUseCase(アイテムを消費し、別のアイテムを獲得する) • DIされたRepositoryを利用してModel / Serviceを取り出し、ビジネスロジックを順に実行 Model
  10. ©MIXI 23 Presentationレイヤ  Presentation UseCase DAO Entity Response Request MasterData

    Service IRepository Repository Action • ゲームクライアントとのやりとりを担うレイヤ • クライアントからのリクエストに応じて必要なUseCaseを実行し、 実行結果をクライアントの求める形式のレスポンスに変換し、返却する Model
  11. ©MIXI 24 Presentation Repository UseCase DAO Entity Response Request MasterData

    Service IRepository Repository Action • DB上に永続化されたユーザーデータや、メモリ上にキャッシュされたマスタデータからModelを再構築する • ビジネスロジックは持たず、Modelの永続化に集中する • UseCaseから利用する場合にはインタフェースを介して依存性を逆転する Model
  12. ©MIXI 27 Keep • 新機能はアーキテクチャに則って実装されるようになった • レイヤ毎の依存関係が制御されるようになった • チーム内で設計に関する議論が活発に行われるようになった •

    GitHub Discussionsに議論の場を用意 • 普段の開発中に気になったことや提案を記録し、週次定例で繰り返し議論の場を設けるようになった • レビューがアーキテクチャを中心に行われるようになった • 共通認識を持てているので議論が捗る • テストを書く文化が生まれた • 新アーキテクチャ導入前のテストカバレッジ(Line) : 0.6% • 新アーキテクチャ導入後のテストカバレッジ(Line): 12% • 新実装に限ると7割程度
  13. ©MIXI 28 Problem • ボイラーテンプレートコードによる実装スピードの低下 • 特にRepositoryの実装において頻発 • 曖昧なルールが混乱を呼んでしまった •

    特にServiceの用途が理解されづらく、乱用されがちになった • 議論の結果決まったルールの集約が甘く、 新メンバーのオンボーディングにかかるコストが増加した(新たな暗黙知の発生) → デザインドキュメントを常に最新の状態に保つコスト   設計意図をチーム内に浸透させるコストを惜しんではいけない • ユニットテスト自体のメンテナンス性はまだまだ課題が残る状態
  14. ©MIXI 32 まとめ • サーバーアプリケーションの内部品質向上・チームのスキルアップを目的として 新アーキテクチャの導入を進めました • 新規機能を新アーキテクチャで実装しました • 実装スピードはやや低下したものの、テスタブルな設計になりました

    • チームもアプリケーションと共に成長しました • 事業部全体を巻き込んで既存機能の書き直しに動き出しつつあります • より多くの価値をユーザーに届けるために これからも技術負債の解決を進めていきます!