設計思想や実装意図まで徹底的に読み解いた設計フェーズ
極めて大規模な再構築プロジェクトになるため、計画や準備にはエンジニアだけでなくプロジェクト全体として半年間かけてじっくり臨んだ。その後まずフェーズ1として「編成関連」の機能のリファクタリングを行い、次にフェーズ2として「クエスト関連」の機能、最後にサービス全体の機能を使用して動作する「バトル関連」のリファクタリングをフェーズ3として行う計画とした。なお本稿執筆時点(2024年2月)では既にフェーズ2までの作業を終えており、残るはフェーズ3のみとなっている。
リファクタリングの方針としては、アーキテクチャに至るまで刷新するため、関数単位の置き換えではなくAPI単位で移植を行い動作を保証する方針とした。そのためAPIのインタフェースは極力現状を維持することとし、これによりEtoEのテストを可能にした上でリリース後に万が一問題が発生してもAPI単位でリファクタリング前に容易に切り戻しできるようにした。また全体のアーキテクチャには「クリーンアーキテクチャ」を採用し、各コンポーネント間を疎結合で連携させることで変更や拡張に強いアーキテクチャを志向した。
さらにはシステム全体でデータアクセスを一元管理する「データマネージャー」の仕組みを新たに取り入れ、データアクセス処理をカプセル化することでデータアクセスの安全性を担保するとともに、キャッシュサーバーやデータベース負荷の画一的な最適化を図った。
一方、このリファクタリング作業を実際に行う主な人的リソースは伊藤氏を含むサーバーサイドエンジニア6名と、この規模の再構築プロジェクトとしてはかなり小規模の体制で臨むことになった。そこで少ない人数でも最大のパフォーマンスを発揮できるよう、開発効率を最大化するためにさまざまな工夫を凝らした。
「まず上流の設計工程でオリジナルのソースコードの仕様と実装を読み解くのですが、単に動作をなぞるだけではなく、本来の『設計思想』『実装意図』までをしっかり読み解いた上で再設計するようにしました。その上で設計品質の画一化のため設計のレビューを行い、調査不足を検知するだけでなく設計思想や実装方法などの理解に曖昧な点が残らないことを徹底しました」(伊藤氏)
設計にしっかり時間をかけることで設計工程における工数は増えるが、設計の品質を高める事で、下流の実装やコードレビューの手戻りを減らし、結果として全体の工数を大幅に削減した。
リファクタリング後にシステム性能が大幅向上
設計フェーズだけでなく実装フェーズにおいても、作業効率を最大化するためにさまざまな工夫を凝らした。ここでもアーキテクチャや設計思想に関する開発メンバーの理解を重視し、方針から逸脱した実装が行われないよう徹底した。プロジェクトに参画してまだ日が浅く、アーキテクチャや設計思想の理解が浅いメンバーは、必ず理解度の高いメンバーとともにペアプログラミングを行うことでメンバー全員への方針の浸透を図った。
「たとえ開発歴が長いメンバーであっても、今回のアーキテクチャや設計思想に対して共通認識を持ってもらうため、この点については決して聖域を作らず、すべてのメンバーに理解してもらいました」(伊藤氏)
また、たとえリファクタリングを既に実施したコードであっても、そこで問題が見付かれば決して妥協することなく再リファクタリングを行う事を徹底した。こうしてチーム内の意識や理解を統一することで、「チーム内で設計に関する議論が、共通認識の下で活発に行われ、それらがチームの設計やソースコードの品質を高め、開発速度の向上にも寄与しました。やはりチームで技術的な課題を共有して、オープンに議論できる文化を作ることが大事だとあらためて実感しました」と伊藤氏は振り返る。
こうした地道なリファクタリングを重ねた結果、システムに掛かる負荷は確実に軽減している。例えば、性能検証の結果としてレスポンスタイムがリファクタリング前の101ミリ秒に対して、リファクタリング後は61ミリ秒と40%短縮した。またスループットも、WEBサーバー1台辺りリファクタリング前は分間2万リクエストだったのがリファクタリング後は3万2000リクエストと、1.5倍のアクセスをさばけるようになった。