【CEDEC2021 フォローアップ】大規模Unityゲーム開発の設計事例 〜 資料公開とドメインモデリングについて

CEDEC2021にて「大規模Unityゲーム開発の設計事例 〜ドメイン駆動設計とDIコンテナを導入した一年を振り返る〜」というタイトルで設計についての講演を行いました。講演をご覧になってくださった皆様に改めてお礼申し上げます。

発表した資料はCedilにて公開されていましたが、内容をブラッシュアップし、あらたにspeakerdeckでも公開しました。ぜひご覧下さい。


ドメインモデリング

CEDECの講演では実装パターンをメインにご紹介しました。実装パターンの他にも、DDDの重要な要素としてドメインモデルの概念があります。現状、モデリングの手法や実施に関してはメンバー個々に任せられており、チームの中でこれといった手法が定まっているわけではありません。まだ模索段階ではありますが、CEDECの公演では触れられなかったドメインモデリングについてご紹介します。

evans本に登場するドメインモデルには、このようなものがあります。

ドメインモデルは重要な要素ながら、evans本にはモデリングの具体的なやり方が書かれておらず、既知のものとして話が進んでいきます。

まずは代表的なやり方、型を知っておきたいところです。きちんとしたドメインモデリングの定義も分からず、どうやってやるんだろう?とかなり悩んだのですが、こちらの本にかなり分かりやすく説明されています。

ユースケース駆動開発実践ガイド | ダグ・ローゼンバーグ, マット・ステファン, 三河淳一, 佐藤竜一, 船木健児 | コンピュータ・IT | Kindleストア | Amazon

この書籍を読み、今までボンヤリとしていたドメインモデリングについて、具体的なイメージを掴む事ができました。evans本に登場するドメインモデルの概念ともほぼ一致します。

ユースケース駆動開発実践ガイドの第2章に、「ドメインモデリング」という、そのものズバリな章があります。この書籍ではドメインモデリングをして終わりではなく、その後にユースケース図、要求レビュー、ロバストネス分析… のように、さらに深堀りしていき、最後にコードに落とし込みます。理想的には全てやりたいところですが、これをチームに浸透させるのはなかなかにハードルが高いと感じました。 (ここがDDDの実践で難しいと感じるところで、一人だけ詳しくなっても効果は薄く、チーム全体で実践する必要があると思っています。)

そのため、ひとまずは第2章「ドメインモデリング」の手法から始めようと考えています。

ここからは、この章を参照しながらドメインモデリングについて紹介していきます。


ドメインモデルとは何か?

ユースケース駆動開発実践ガイドではこう紹介されています。

ドメインモデルとは、本質的にはプロジェクトの用語集だと言って差し支えありません。つまり、プロジェクトで実際に使われているすべての単語を収録した「ライブ」辞書です。しかしドメインモデルは、たんなるプロジェクトの用語集よりもはるかに優れています。というのも、それぞれの単語間の関係がグラフィカルに表現されているからです。

ユースケース駆動開発実践ガイド

これも非常に腑に落ちる表現でした。プロジェクトで辞書として採用されるまでには相当な熟達が必要そうですが、もしそうなればチーム全体で共通のモデルが出来たという事で、かなりの効果を発揮しそうです。こちらの書籍の説明では、プログラムに落とし込むためのものというより、ユビキタス言語に近いイメージです。

上に挙げたevans本の例と少し違うのは、モデルの振る舞いには踏み込まず、has-a、is-a 関係だけを記述する事に留める部分です。これはドメインモデリングの後に、さらに分析が続くからです。

ドメインモデルの書き方

ドメインクラス間の汎化(is-a)集約(has-a)関係で表現していきます。

この図でいうと、キャラクターはアイテムを持っています(has-a)。所持している側に白い菱形を表示します。

猫は動物の子クラスです。つまり、猫は動物の一種です(is-a)。ここで間違いやすいのは、is-aの矢印の向きについてです。参照の方向を表すため、子クラスから親クラスに向かって矢印が伸びます。

ドメインモデリング ガイドライン

書籍には、ドメインモデリング ガイドラインのトップ10が記載されています。その中で個人的になるほど、と思った項目を紹介します。

6.ドメインモデルをデータモデルと勘違いしてはいけません。

5.オブジェクト(単一のインスタンスを表現する存在)とデータベースのテーブル(モノの集合を含む存在)とを混同してはいけません。

こちらは、cedecの発表でも紹介した、データベースのテーブルをエンティティとして扱ってしまった経験を思い出しました。

最初のドメインモデリングにかける時間を2時間に限定しなさい

(以上、ユースケース駆動開発実践ガイドより引用)

evans本にもあるのですが、最初から完全なドメインモデリングは出来ず、徐々に洗練されていくもの、とあります。こちらの書籍では、2時間のブレスト形式のセッションで、80%のドメインクラスが発見できる、と書かれています。

実際のドメインモデリングの流れ

書籍では「インターネット書店」を題材にして話が進みます。amazonを想像して頂ければ大丈夫です。題材となる例が分かりやすいのも、この書籍の特徴です。

まず、インターネット書店に対する要求が提示されます。下記に一部を抜粋します。

2.書店はインターネットから注文を受け付け、書籍を売ることができなければなりません。

3.ユーザーは精算前に、オンラインショッピングカートに書籍を加えることができなければなりません。

a.同じように、ユーザーはショッピングカートから品目を取り出すことができなければなりません。

6.ユーザーはクレジットカード発注書で支払うことができなければなりません。

9.システムが(名前、住所、クレジットカードといった)ユーザーの詳細情報を記録できるようにするため、ユーザーはログイン時に顧客アカウントを作成できなければなりません。

a.システムは中央データベースにあるアカウントリストを修正できなければなりません。

b.ユーザーのログイン時には、そのユーザーのパスワードがマスターアカウントリスト内のパスワードと常に一致していなければなりません。

(以上、ユースケース駆動開発実践ガイドより引用)

これらの要求仕様から、まずDDDにおけるユビキタス言語が明らかになっていきます。主に太字になっている部分です。また、このユビキタス言語はドメインクラスの候補でもあります。これらをもとに、is-a、has-a関係を図にしていきます。上記の要求から、まずこのようなドメインモデリングが出来上がります。

これに対し、チームで話し合い、認識に齟齬がないか、足りないモデルが無いかをチェックしていきます。その過程で足りないドメインモデルが発見されたり、別のものだと思われていたモデルが実は統合できたり、粒度が小さすぎてモデルとしては不適切なもの等が判明していきます。これはevans本でも度々登場するシーンです。

最終的に、このようなモデルが作られます。

さらにもう一冊、参考にさせて頂いた書籍があります。

ドメイン駆動設計 モデリング/実装ガイド – little-hands – BOOTH

こちらの「ドメイン駆動設計 モデリング/実装ガイド」で紹介されているドメインモデリングはもう少しクラス図寄りのもので、メソッド・プロパティも記述し、多重度、集約に関してもドメインモデリングの対象にしています。

また、ユースケース駆動開発実践ガイドとは順番が逆で、ユースケースを作ってからモデリングを実施する形式になっています。

ユースケース駆動開発実践ガイドについてはこちらの書籍でも紹介されています。しかし、その手法を全て実践するのはなかなかハードルが高いため、上記の形式が提案されています。

これらの手順で明らかになったドメインモデルを、そのままC#のクラスに落とし込み、プログラムを書いていきます。データや処理の順番、使い勝手を元にクラスが作られるのではなく、ドメインモデルを元にクラスが作られる事で、OOPが促進されると考えています。ドメインモデルに対してはテスト、契約による設計を積極的に適用していく予定です。

このような図を書く際、良くdraw.io (diagrams.net) を使っていますがgit管理には適しません。そのため、git管理するなら書籍で紹介されているように、plantUMLを使うのが良さそうです。(C#エディター・RiderのplantUMLプラグインを使ってpreviewしています。)

こういったumlに対して

@startuml
object 書籍レビュー
object 書籍カタログ
object 書籍
object ミニカタログ
object マスター書籍カタログ
object 編集者レビュー
object 読者レビュー

書籍 o-- 書籍レビュー
書籍カタログ o-- 書籍 

書籍カタログ <|-- ミニカタログ
書籍カタログ <|-- マスター書籍カタログ

書籍レビュー <|-- 編集者レビュー
書籍レビュー <|-- 読者レビュー
@enduml

このような図が生成されます。

書籍ではplantUMLのobject図ではなくクラス図で作成されていましたが、最初にユビキタス言語を羅列していく形式が良いのでは、という事でobject図で書いてみました。

運用

手法に関しては理解できたのですが、これをどうやって運用してくのか、少し悩みました。

ひとまずは

機能実装の際、まずドメインモデリングを実施し、メンバー間で認識に齟齬がないか確認。pullrequestの際にもモデル図を添付する

といった感じでしょうか。ドキュメント用ディレクトリを用意し、そこでpumlファイルを管理していく形にしてみました。

実際にやってみて

ゲーム中、複雑になりがちな「スキル」関連の実装についてドメインモデリングを実施してみました。

概念が図になり、議論がとても捗りました。捗るどころか、おそらくモデル図が無かったら議論が無理だっただろう、と感じます。

想像以上の効果があったので、今後も積極的に実施していこうと思います。

まとめ

ドメインモデリングを実施し、ドメインエキスパート(私達のチームではディレクター・プランナー)とも認識を共有できれば、かなり効果を発揮できるでしょう。

(理想的には、書籍で後に紹介されているロバストネス分析あたりまでドメインエキスパートがたたき台を作ってくれると、かなり楽になるのではないか? と妄想しています。)

その他にも実装前におけるメンバー間での認識合わせ、その後のコードレビュー等にも役立つでしょう。

DDDにおいて、実装パターン比べるとドメインモデリングは抽象度が高く難しく感じます。

しかしその分、実施した際の効果も大きいはずです。

この記事がドメインモデリングの参考になると幸いです。最後まで読んでいただき、ありがとうございました。


関連記事一覧

  1. この記事へのコメントはありません。