コロプラ・ベアーズ 面白いものを作りたい仲間が集まるベアーズ

コロプラのエンジニアブログ Vol.4【『白猫』システムのモダン化】
TEAM

コロプラのエンジニアブログ Vol.4【『白猫』システムのモダン化】

T.I

2016年2月、サーバーサイドエンジニアとして中途入社。現在は『白猫プロジェクト』と新作タイトルを担当し、リーダー職も務める。

ミッション

2018年、それまで担当していたゲームタイトルの運用チームから『白猫プロジェクト(以下、白猫)』へ配属になり少し経った頃、一つのミッションを与えられました。

いくつかイベントを担当し、ある程度どのようなシステムかは分かりかけていましたが、『白猫』は2014年7月にリリースされたタイトルのため、そのコードは膨大で深く、把握するにはそれなりに時間が掛かっていました。
解決策はないのかと考えていた時、与えられた「システムのモダン化」というミッションでした。これから『白猫』がさらに長期運用を迎えるにあたり、抱えていた課題の改善を行い、さらに先を見据えた基礎を構築する必要がありました。

engineer_blog_vol4_800_500_1.png

課題

当時時点で、リリースから4年以上運用されていたコードは、追加や派生が繰り返され複雑に絡み合い、ステータス変更はどこで起こっているのかなどの判断がつきにくく、肥大したクラスはIDEがフリーズするほどでした。
とはいえ、ここまで積み重なった実装に対してドラスティックな変更を加えることは非常にリスクが高く、ただ理想を突きつければ解決するような話ではありませんでした。リスクを最低限に抑え、どう長期運用を見据えたシステム基盤へと変えていくのか、落とし所を模索し、効果を発揮できるものにする必要がありました。

解決策

課題解決を行うためにまず、
「布石を残すこと」「共通認識を持つこと」
が改善への第一歩だと考えました。

リスクを最低限に抑えつつ、理想に近づけるために必要なものは、今足りない機能や置き場所に困る処理の居場所を作ることにありました。必要な機能がないと似通った処理が増え、行き場をなくした処理は雑多に置かれることになります。
居場所ができたあとは、それを活かすために今後どうしたいのかをメンバーに伝えて、共感を得て浸透させていくフェーズに入ります。

テーマ

既存コードを見渡すと肥大したクラスは役割が不明瞭になっており、複雑に絡み合ったコードは依存関係を曖昧にし解読を困難にしていました。
現状の課題を整理し方向性を明確にしたいと考えた時、
「役割」「依存関係」
の2点をテーマにシステム構成の見直しを進めることで、改善に繋げられると感じました。掘り下げると恐らく様々な意見が出るだろうとは思いますが、落とし所を見据えた上で、方向転換をする際の拠り所にできそうなポイントはここだと思い、テーマとしました

実施したこと

具体的に実施したことに関しては、要点だけ抜粋すると、
● モデルの活用
● serviceの導入
● アプリケーションcoreの導入
● エラー制御の整理
● PHPUnitの導入
● 依存関係の共通認識
です。

内容を少し掘り下げて紹介します。

ー モデルの活用

当時のモデルにはアクセサのみが自動生成され、ビジネスロジックを置く余地がない状態でした。そこでまずアクセサをtraitに分離し、空のモデルクラスを生成することにより、エンティティーに直結するビジネスロジックの居場所を作りました。
結果、散在していたビジネスロジックはモデルに集まってくるようになり、役割過多になっていたクラスのスリム化が進んでいます。

engineer_blog_vol4_800_700_7.png

ー serviceの導入

DI(Dependency Injection)を利用できるようにしたのと、エンティティーに直結するビジネスロジックだけでは完結できないビジネスロジックの居場所として用意しました。当時からアクションヘルパーは存在しましたが、本来の役割と少しずれを感じたのと、明確にドメイン層として存在するものが必要だったので導入しました。
これを入れることにより、アプリケーション層とドメイン層の依存関係を薄くすることができ、DIでモジュール間の依存も管理しやすくなりました。また、構造的にSOLID原則も意識しやすくなります。

ー アプリケーションcoreの導入

アプリケーションの中核ロジックを置く場所も用意しました。開発をしていく上で、ビジネスロジックやリクエスト操作とも違うアプリケーション基盤として必要なロジックが出てきますが、居場所がないと似通った処理が至る所に増えることになるので、アプリケーション共通ロジックとしてのレイヤーを用意することにしました。
ここには主に共通で使われる文字列や時間管理、外部ソフトウェアとの仲介が存在しています。

ー エラー制御の整理

エラーコードは用意されていたものの、処理毎に手作りされていたエラー管理を一元管理できるようにし、予期したエラーと予期しないエラーを明確に分けることで実装コストを下げられました。影響範囲が広いため、古い箇所は旧処理のまま動いていますが、少しずつ新処理系統の箇所は増えています。

ー PHPUnitの導入

長期運用を見据えた時、変化しないシステムはあり得ないので、変化に強いシステムにすることが長期運用をしていく上で最善の解だと考えています。その時に変化を担保する上でも重要な役割を担ってくる機能になって来ます。

ー 依存関係の共通認識

役割を増やしたものの、依存関係が整理されていないと役割が崩壊し、不安定な具象処理に依存しすぎると変化を阻害します。
リクエストから始まり、処理が適切なフローで流れ、各serviceが必要なモデルを操作してアプリケーション層へと結果を返していく。一連の流れと、適正な役割で働き、処理を適切に委譲していくことで依存関係を保ち、構造の輪郭が見えることで全体把握もしやすくなります。
また関係者に向けた説明会をするなどして共通認識を持つことで、中長期を見据えた最終イメージを全員で共有できるようにしました。

engineer_blog_vol4_800_500_5.png

まとめ

今回の対応は、一つの転換点としての提案をシステムに残しましたが、運用で変化し続けるシステムに答えはなく、一つの方向性の基、常に状況を見ながら最適の解を模索し続けることこそが、システムの寿命を延ばすのだと思います。
この対応で、今まで曖昧だった処理や散開していた処理は明確に居場所ができ、依存が整理されることでシステム把握がしやすくなりコードリーディングでの精神的負担も減りました。そして、あくまで転換点の布石として増えた機能やレイヤーたちの真価が問われるのは恐らく数年後です。

今回は代表としてこの記事を書かせて頂きましたが、一人で対応した訳ではなく、また『白猫』のサーバーには多くの人が関わっており、全員の理解と協力があったからこそ前進することができました。

最後に。この対応で私がしたことは一つの例であって、もっと良い解があったのかもしれません。しかし変化は少しずつ現れて来ています。『白猫』を支えるバックエンドシステムとしてさらに改善されていくものと期待しています。