MVPパターンを採用したツール開発の効果

サムネイル

はじめに

こんにちは。EXNOAの技術推進部クライアントグループ所属の宮本です。

EXNOAでは、DMM GAMESプラットフォームの開発、運営やオンラインゲームタイトルの開発、運営、パブリッシングを行っています。
技術推進部は横断組織として、EXNOAが開発、運用しているオンラインゲームを技術的にサポートしています。

本記事では、EXNOAが開発するゲームのパフォーマンスチェック&デバッグを行うツール「NOA Debugger」を開発するにあたり、MVPパターンを採用した経緯とその結果について共有します。

開発したツールについて

技術推進部ではリリース前ゲームのパフォーマンスチェックを行う業務が定期的に発生します。
それらの業務を効率化するため、私たちはパフォーマンスチェックツール(NOA Debugger)を開発しました。

最終的にパフォーマンスチェックのみならず、デバッグにも幅広く活用できるように調整し、UnityのAssetStoreへ展開しました。

NOA Debuggerではランタイム上でメモリ等のプロファイル情報、APIやコンソールログの確認、カスタマイズ可能なデバッグツール。などの機能が集約されており、ゲームのパフォーマンスチェックやデバッグを効率化できるツールとなっています。
ツールについて詳しくは下記リンクから確認できます。
NOA Debuggerのストアページ

MVPパターンとは

MVPパターンとはユーザーインターフェースの開発を効率化するためのアーキテクチャです。
MVPパターンでは、次の3つに役割を分けて機能実装を行います。

役割 説明
Model(モデル) データやロジックを持ちます。
ビューやプレゼンターを知りません。
View(ビュー) 画面表示とユーザーの入力を受け付け、プレゼンターに通知します。
モデルのことは知りません。
Presenter(プレゼンター) モデルから情報を取得し、ビューに対して描画命令を行います。
ビューから受け取った入力情報を処理し、モデルに反映します。
モデルとビューについてよく知っています。

関係性のイメージとしては以下になります。

MVP

導入背景

初めに、プロジェクトとして以下の要件がありました。

  • ユーザーのニーズに合わせた機能追加/削除が必要(長期運用の必要性)
  • リリースごとに全機能のテストが必要(テストのコストを下げたい)
  • ツールはシンプルなUIで構築されている

そこで、MVPのメリットである「柔軟性」「テスト容易性」「責務の明確さ」という点を考慮しMVPパターンを採用しました。

MVPを取り入れたことによる効果

MVPを取り入れたことにより以下の効果を感じました。

ビューが増えた時の対応が容易である

NOA Debuggerでは、メイン画面に加え、ゲーム操作中でもパフォーマンスチェックやデバッグツールを扱えるようフローティングウィンドウとしても表示できます。
また、様々な利用環境を想定し、デバイスの向きによるUIの切り替えも実装しています。

view-samples

表示する要素は変わらないものの、UIの構成は異なるものとなっています。
MVPを採用したことにより、同じモデルからの情報を別々のUIに表示するといった実装が容易でした。

また、ツールのリリース後、UnityEditorのGUI上で機能を動作させるツールの拡張が必要になりました。
ロジック部分には変更がなかったため、新たにエディタ用のビューを作成するだけで実装が完結し、実装コストを下げることができました。
さらに、すでに安定して動作している処理をそのまま利用しているため、機能追加による不具合も抑えることができています。

ロジック部分のテストが書きやすい

UIの処理とロジックの処理が分かれているため、ロジック部分のテストをすべて「Unity Test Runner(Unityの自動テスト)」で記述ができました。
UIの検証には手動テストが必要になりますが、自動テストを取り入れることで検証全体のコスト削減が実現できました。

また、「モデルのテストは自動テストで記述する」という考え方を適用しやすいため、実装者によるテスト作成のブレを抑えることができました。

課題点

一方でMVPパターンを取り入れたことによる課題もいくつかありました。
チームとしてMVPパターンを活用するのが初めてだったため、上手に活用できていない点もあったかと思います。
別のプロジェクトでMVPを採用する際は、この辺りの経験も活かせればと思います。

プレゼンターが肥大化しやすい

プレゼンターはモデルとビューを繋ぐ役割のため、複合的な処理がプレゼンターに集約されます。
その結果プレゼンターが肥大化しやすく、コードの可読性を低下させるおそれがあります。

本プロジェクトではツールの機能ごとにプレゼンターを用意する方針です。
プロジェクトの初期はプレゼンターの適切な共通化ができておらず、必要な処理が全てのプレゼンターに直接記述されていました。
その結果プレゼンターが肥大化し、冗長な処理が増えていました。

共通処理の部分は基底クラスに集約するなど、クラス設計を適切に行い、冗長なコードを抑える工夫が必要でした。

MVPパターンに属さないクラスの置き場所が乱雑になりやすい

設計の初期段階で、MVPパターンに属するファイルのディレクトリ構成は固めることができました。
一方でマネージャーやコンポーネントなど、MVPに属さないファイルは全て「Scripts」配下へ乱雑に配置されており、後から見返した時に欲しい情報へすぐに到達できない問題がありました。

<root>
├── Presenters
├── Views
├── Models
└── Scripts
    ├── XXXManager.cs
    ├── YYYComponent.cs
    └── ZZZDataInfo.cs

開発を進めていく中でMVPパターンに属さないクラスも必ず必要になってきます。
基本設計でMVPパターンを採用した場合、その部分は詳細に設計しますが、他の部分の設計が疎かになりがちでした。

初期設計の段階で、周辺クラスの設計もしっかりと固めることができていれば、よりよいディレクトリ構成にできたのではと感じます。
とはいえ、初期では想定できない部分も多いため、その都度チームメンバーと話し合い、適切な配置場所を検討するのが望ましいと思います。

まとめ

今回のプロジェクトで立ち上げから運用まで一通り経験した結果、ツール開発とMVPパターンの親和性は高いと感じました。

ツール開発ではニーズに合わせた機能改修が多く発生するため、責務を正しく分割し、柔軟な開発を実現する必要性を感じます。
また、定期的なリリースが必要だったため、検証コストも無視できません。
すべてを自動テストで補うのは難しいのですが、可能な限り自動テストを取り入れることで、検証コストの削減が見込めます。

MVPに慣れていなかった部分もあり、いくつか課題も浮き彫りになりましたが、うまく共存することで柔軟性の高いツール開発が期待できると思います。

最後に、技術推進部クライアントグループでは一緒に働いてくれる仲間を募集しています。
ご興味のある方は、ぜひ下記の募集ページをご確認ください!
dmm-corp.com

' }) e.innerHTML = codeBlock; });