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

形から入ったドメイン駆動設計によるゲーム開発の光と闇

Df4978f14401325586e9e286b140ac4c?s=47 n1215
October 23, 2019

 形から入ったドメイン駆動設計によるゲーム開発の光と闇

TECHxGAME COLLEGE #28(https://techxgamecollege.connpass.com/event/148035/) の発表資料です

Df4978f14401325586e9e286b140ac4c?s=128

n1215

October 23, 2019
Tweet

Transcript

  1. TECH×GAME COLLEGE#28 形から⼊ったドメイン駆動設計によるゲーム開発の光と闇 2019年10⽉23⽇ (⽔) 株式会社Nextat 中榮健⼆ Nextat Inc. 1

  2. お詫びと訂正 本⽇はDDDの核⼼部分の話はしません この煽り⽂の答えが出ないことをお詫びして訂正いたします Nextat Inc. 2

  3. ⾃⼰紹介 京都から来ました - 中榮健⼆ (なかえけんじ) - twitter: @n_1215  - 株式会社Nextat

    取締役 - baserCMS コアコミッター(最近コミットしてない) - Laravel + Unity でソシャゲ開発など Nextat Inc. 3
  4. 発表概要 1. ドメイン駆動設計の概要と軽量DDD 2. レイヤ・クラス分割の話 3. ユビキタス⾔語が統⼀されなかった話 4. 10分経っても返ってこないガチャAPIのチューニングの話 5.

    境界づけ(られなかっ)たコンテキストの話 6. ちょっと深いモデルの話 Nextat Inc. 4
  5. 参加者の皆様に質問 ゲーム業界の⽅? 趣味でゲームを開発されている⽅? サーバサイドの開発者の⽅? ソシャゲをやったことがある⽅? Nextat Inc. 5

  6. DDDについて 聞いたことがある⽅? 開発に取り⼊れている⽅? Evans本を読んだことがある⽅? Nextat Inc. 6

  7. Domain Driven Design (ドメイン駆動設計)の概要 Nextat Inc. 7

  8. DDDの概要 開発者・顧客や業務の専⾨家を含む関係者の間で、共通の⾔葉とメンタルモデル を育てシステムを開発していく⼿法 戦略 共通の⾔葉を作り業務をドメインモデルとして表現する 戦術 設計・実装の技術的パターン、オブジェクト指向のベタープラクティス Nextat Inc. 8

  9. ⽤語 ドメイン ソフトウェアを作る対象となる問題領域 モデル 事象の特定の側⾯を抜き出し簡略化した模型のようなもの。 ex. 数理モデル ドメインエキスパート 問題領域に詳しい専⾨家 ユビキタス⾔語

    ドメインモデルを表現するためのチームメンバ全員によって使⽤される共通の⾔語 Nextat Inc. 9
  10. DDDの根本の仮定 ドメインエキスパートと協⼒してドメインを理解し、モデルを継続的に改善する この仮定が成⽴しない開発現場もある Nextat Inc. 10

  11. 開発がイテレーティブではない とか Nextat Inc. 11

  12. 上流から表計算ソフトで書かれた設計書だけが流れてくる とか Nextat Inc. 12

  13. ドメインエキスパートと開発者が対話できる環境がない とか Nextat Inc. 13

  14. ドメインエキスパートがそもそもいない とか Nextat Inc. 14

  15. 現実は厳しい 組織やプロセスの根本の改善から始める??? 開発者⾃⾝がドメインエキスパートになる??? DDDを実践することができないのか!? Nextat Inc. 15

  16. 軽量DDD(戦術的DDD) Nextat Inc. 16

  17. 軽量DDD(戦術的DDD) DDDの戦術的パターンの⼀部だけをつまみ⾷いする⽅法 戦術的パターンの例 レイヤ化アーキテクチャ Repository、Factory、Entity、Value Object Speciaficationパターン Nextat Inc. 17

  18. 軽量DDDへの批判、失敗談 戦術的DDD、軽量DDDと聞くと⼀⾒聞こえはいい 悪く⾔えば形から⼊ったDDDもどき 戦略的なドメインモデリングを取り⼊れた時のようなメリットは薄い "◦◦FWでDDD"などと発⾔すると反応が冷たいのはこのせい Nextat Inc. 18

  19. 今⽇は軽量DDDを中⼼にした話をします メリットが薄いとは⾔え、効果がないわけではない 戦術的パターンの解説だけでも結構な分量がある オブジェクト指向設計の指針として 開発者が触る部分だけでも歴戦の開発者の知⾒を参考にできる 戦略的ドメインモデリングを実践する前の基礎として 戦術を理解することで細部に捕らわれることがなくなり、より重要なモデリング の話に集中できる Nextat Inc.

    19
  20. お話しするソーシャルゲームの想定 キャラクターの育成 ガチャによるキャラクター、装備品の⼊⼿ ストーリーを進めてバトル タップ中⼼の簡単なUI Nextat Inc. 20

  21. お話しするゲームシステムの主な構成 ゲームサーバ: PHP + Laravel ゲームAPI: Web, Android, iOSに対応するため、JSONを返すAPI マスタデータ管理画⾯:

    マスタデータ作成・更新のための機能。HTML CS管理画⾯: ユーザの⾏動履歴などお問い合わせ対応⽤の機能。HTML データベース: MySQL、Redis クライアント: Unity、 JavaScript Nextat Inc. 21
  22. 注1: "ドメインエキスパートがいない"などと煽っておいてアレで すが、関係者の皆さんとの話はしやすいプロジェクトでした 注2: ⼀部実際のコードや⽤語などを簡略化・変更して掲載してい ます Nextat Inc. 22

  23. 1. レイヤ・クラス分割の話(光:闇 = 3:7) Nextat Inc. 23

  24. 分割しない例:典型的なWeb MVCフレームワーク による開発 Model View Controller Nextat Inc. 24

  25. Model Eloquent (ActiveRecord系のORM) の"モデル"を継承しただけ クエリ発⾏、DB保存、ドメインロジックを全て⾏う class UserCharacter extends \Illuminate\Database\Eloquent\Model {

    } Controller class UserCharactersController { public function lock(int $userCharacterId): JsonResponse { $userId = auth()->id(); $userChara = UserCharacter::whereUserId(userId)->findOrFail($userCharacterId); $userChara->is_locked = true; $userChara->save(); return response()->json($userChara->toArray()); // この辺りがView } } Nextat Inc. 25
  26. 定番の戦術1. レイヤ化アーキテクチャ レイヤ 責務 UI (Presentation) ユーザに情報を表⽰、ユーザのコマンドを解釈 Application ソフトウェアで⾏う仕事の定義。ドメインオブジェクトにより問 題を解決

    Domain (Model) ビジネスの概念、情報、ビジネスルールを表現 Infrastructure 上位のレイヤを⽀える⼀般的な技術的機能を提供 Nextat Inc. 26
  27. 複雑なプログラムをレイヤに分割 各レイヤは下位層だけに依存 Evans本ではドメイン層を隔離し、ドメインオブジェクトがドメインモデルを表 現する事に専念させることを強調 Nextat Inc. 27

  28. 定番の戦術2. ドメイン、インフラ層のクラス達 エンティティ(Entity) 値オブジェクト(Value Object) サービス(Service) ファクトリ(Factory) リポジトリ(Repository) Nextat Inc.

    28
  29. エンティティ(Entity) 時間経過などによりその属性が変化しても同⼀とみなすオブジェクト 要は固有の識別⼦=IDを持つもの ex). ユーザ所持キャラクター Nextat Inc. 29

  30. ex). ユーザ所持キャラクター(略式) class UserCharacter { /** ID */ private $userCharacterId;

    /** キャラクター(マスタ) */ private $character; /** 攻撃⼒などのステータス */ private $status; /** ロックされているかどうか */ private $isLocked; public function lock(): void { $this->isLocked = true; } } Nextat Inc. 30
  31. 値オブジェクト(Value Object, VO) その値だけが重要なモデルは値オブジェクトとして分類する 不変(Immutable)なものとして扱う ex) ユーザ所持キャラクターのレベル、レアリティ、名前 ... Nextat Inc.

    31
  32. ex) キャラクターのレアリティ class CharacterRarity { /** @var int */ private

    $value; public function __construct(int $value): void { if ($value < 1 || $value > 5) { throw new \InvalidArgumentException(' レアリティは1 以上5以下の整数'); } $this->value = value; } public function getValue(): int { return $this->value(); } } Nextat Inc. 32
  33. ファクトリ(Factory) 複雑なドメインモデルの⽣成ロジックをカプセル化して内部の実装を隠蔽する 主としてドメインモデルの新規⽣成、永続化したデータからの再構成の2種類に分 かれる Nextat Inc. 33

  34. ex) キャラクターのファクトリ class CharacterFactory { public function makeFromRecord(CharacterRecord $record): Character

    { return new Character( new CharacterId($record->id), new Name($record->name), new Rarity($record->rarity), // 略 ); } } Nextat Inc. 34
  35. リポジトリ(Repository) Entityのデータストアへの永続化、およびデータストアからの取得・検索 Entityのコレクションをエミュレートし、メモリ上にあるかのように扱う 通常、Interfaceを⽤意してドメイン層からは永続化の詳細を気にさせない Nextat Inc. 35

  36. ex) キャラクターのリポジトリ class CharacterRepository { public function find(CharacterId $characterId): ?Character

    { $record = CharacterRecord::query()->find($characterId->getValue())); if ($record === null) { return null; } return $this->characterFactory->makeFromRecord($record); } } Nextat Inc. 36
  37. サービス(Service) ドメインの操作だが、EntityやVOの機能としてモデル化しにくいもの 名詞ではなく動詞的な名前を持つ ex) ユーザ所持キャラクターをロックする操作、強化する操作 Nextat Inc. 37

  38. ex) ユーザ所持キャラクターをロックする操作 class LockUserCharacterService { public function lock(UserCharacterId $userCharacterId): UserCharacter

    { $userCharacter = $this->userCharacterRepository->find($userCHaracterId); $userCharacter->lock(); $this->userCharacterRepository->save($userCharacter); return $userCharacter; } } Nextat Inc. 38
  39. 整理し直す before after UI Controller,View Controller,View Application Controller ApplicationService Domain

    Eloquent Model Entity、VO RepositoryのInterface Factory DomainService Infrastructure Eloquent Model Repository(Eloquent実装) Nextat Inc. 39
  40. Nextat Inc. 40

  41. レイヤ、クラス分割実践時の(光) Eloquent (LaravelのORM)のFat Model化の緩和 POPOで実装したEntity、VOにドメインの機能が分離され明確になる ORMのクエリの発⾏箇所がある程度絞られた VOによる抽象レベルの統⼀と堅牢性 スカラーではなくVOを⾜場に。コードをドメインの⾔葉で書きやすくなる VOのコンストラクタで値の制約を表現。不正なオブジェクトの作成を阻⽌ 引数の順番間違い防⽌など型の恩恵で凡ミスが減少。IDEの静的解析との相性◎

    Nextat Inc. 41
  42. レイヤ、クラス分割実践時の(闇) クラス数の増⼤ 記述量の最⼩化を是とするFW使いとして育ってきていると実装するクラス数の増 加に慣れるまでに時間がかかる 最初のうちはクラスの関係性や全体の処理順序の把握が困難 各クラスの責務の混乱 どのクラスで何をするのか、何をしてはいけないのか共有しきれていなかった た Repository内にデータストアの影響を閉じ込めるはずが、FactoryやService内 でのクエリ発⾏も⾏われていた

    Nextat Inc. 42
  43. 貧⾎ドメインモデル クラスを分割すること⾃体に不慣れな内はEntityの設計まで気が回らない レイヤを分割してRepositoryを作ってEntityの属性をVOでラップした時点で⽴派 なDDDだと思っていた⼈も多数 DBレコードオブジェクトの中⾝を詰め替えただけの全Getter, Setter付きEntity Entityが不変条件を守れない 書いた本⼈の感想「無駄にクラスが増えただけでは。やはりEloquentこそ⾄⾼」 そらそうよ Nextat

    Inc. 43
  44. フロントエンドの分割が過剰だった話 なぜかサーバ側より複雑……? Nextat Inc. 44

  45. 新規実装・修正のコストが嵩んだ 表⽰するだけの機能には過剰であった フロント側の処理の⽐重が⾼いドメインでは有効なこともあった ex. フロント側で装備品の強化後のパラメータをプレビュー、⾼速化とサーバ 負荷の減少を狙うケース サーバ側のアーキテクチャをそのまま持ってきても成功するとは限らない Nextat Inc. 45

  46. View駆動開発の深い闇 Viewを元にバックエンドのAPIを考え始める UIに新しい項⽬が必要になると全部修正。層の無駄な多さがネックに。 先にバックエンドのEntityが持つ可能性のある項⽬を検討しておき、APIにも反映 しておく⽅が良かった Nextat Inc. 46

  47. レイヤ分割により、各レイヤ内、特にドメインの実装に専念しや すくなる 各レイヤ、クラスの役割と意味を開発メンバーに共有しておかな いと形骸化する 過剰に分割すると⾟くなることもある。レイヤやクラスの責務と 必要性を考えるべき Nextat Inc. 47

  48. 2. ユビキタス⾔語が統⼀されなかった話(ほぼ闇) Nextat Inc. 48

  49. Therefore its name was called Babel, because there the LORD

    confused the language of all the earth. And from there the LORD dispersed them over the face of all the earth. https://biblehub.com/esv/genesis/11.htm The city and its tower Nextat Inc. 49
  50. ユビキタス⾔語と分業 仕様作成者、バックエンド開発、フロント開発、フロントUI開発などと分業して いた事例 ゲーム⽤語がレイヤ化と分業によりたやすく共有できなくなった Nextat Inc. 50

  51. 例1. 仕様書からしてそもそも揺れている 仕様書: キャラ or キャラクター or ユニット バックエンド: キャラクター、ところによりキャラ

    フロントエンド: キャラクター、ところによりユニット Nextat Inc. 51
  52. 例1の対策 仕様書を書く側でなるべく統⼀してもらう 仕様書を読んでいて揺れに気づいたら指摘 Nextat Inc. 52

  53. 例2. ⽤語の指す概念を正しく共有できていない キャラクター(マスターデータ) ユーザー所持キャラクター 仕様書 単に"キャラクター", "キャラクターID"とだけ⾔及される場合も多い ガチャの排出キャラクター (マスタ系) パーティに編成されたキャラクター(ユーザー所持系)

    Nextat Inc. 53
  54. バックエンド 所持:UserCharacter マスタ:Character フロントエンド 所持:Character 特にIDの混乱によるバグが怖い Nextat Inc. 54

  55. 例2の傾向と対策 ⽤語集を作る 共有の場を設ける 開発中に⽂脈で判断できない場合は仕様を再確認 レビューで指摘する Nextat Inc. 55

  56. 例3. 英語名がバラバラ アイテムの数量 itemAmount itemQuantity itemCount など、 バックエンドのEntity フロントエンドのEntity フロントエンドのView

    で揺れているようなケースも Nextat Inc. 56
  57. 例3の傾向と対策 英語圏ではユビキタス⾔語を命名にそのまま利⽤できる 仕様書とプログラムに違う⾔語を使う我々のケースでは⽇英翻訳による差異が発 ⽣ 対訳表をしっかり作った⽅がいい。揺れを発⾒したら追加していく Nextat Inc. 57

  58. おまけ:プログラムを⽇本語で書くのはあり? ⽇英翻訳が⾟いならそのまま⽇本語を使えばいいじゃない → いろいろ⾟い 複数形。characters => キャラクター達? キャラクターリスト? 真偽値を返すメソッドの命名 〜かどうか

    ⽇本語ファイル名で問題が起こるツールも Nextat Inc. 58
  59. 語順も違うし…… 英語:主語(S)動詞(V)⽬的語(0) The user character attacks to the enemy. $userCharacter->attack($enemy);

    ⽇本語: 主語(S)⽬的語(0) 動詞(V) ユーザー所持キャラクターが 敵を 攻撃する $ ユーザー所持キャラクター-> 攻撃する($ 敵) 助詞もないし⽚⾔っぽい Nextat Inc. 59
  60. 参考:なでしこ ⽇本語プログラミング⾔語 ⽇本語の語順に対応 https://nadesi.com/doc/kouza/01-1-hello.htm クジラが「こんにちは」と⾔う。 なでしこ3はブラウザで動作するらしい? その他の⽇本語プログラミング⾔語としてはドリトル、プロデルなどがある Nextat Inc. 60

  61. 開発者の間だけでも⽤語を正しく共有することは⼤事 Nextat Inc. 61

  62. 4. 10分経っても返ってこないガチャAPIのチューニングの 話 Nextat Inc. 62

  63. とある開発初期のガチャ抽選API POST /gachas/123/roll Nextat Inc. 63

  64. よーし、回しちゃうぞ〜 フロント HTTPレスポンスのステータスが500 PHP Fatal error: Maximum execution time of

    30 seconds exceeded そうか時間が⾜りなかったか〜 Nextat Inc. 64
  65. PHPのmax_execution_time設定を伸ばす nginx 504 Gateway Time-out Nextat Inc. 65

  66. nginxとPHPの設定値を10分くらいに伸ばす ⻑いのでTwitterをしながら待つ nginx 504 Gateway Time-out だめだこりゃ Nextat Inc. 66

  67. 何が問題だったか 巨⼤な集約 柔軟すぎるマスタの仕様。対価の設定、排出率設定、出現確率アップ、確定設定 などガチャのマスタテーブルだけで20超え ガチャ = ガチャ内容物×1000個がそのままEntityに。純粋に⼤きい クエリ数もさることながら、DBレコードオブジェクトからEntityへの変換にもか なりの時間がかかり、不必要にメモリも⾷っていた DBクエリ

    Repository以外の場所で発⾏されている脱法クエリが多くあった レイヤを分離したことで、FactoryでN+1問題が発⽣していることも Nextat Inc. 67
  68. パフォーマンスチューニングだっ レイヤ・クラスの再整理 クエリの発⾏を把握しやすいようにレイヤの役⽬を再整理 FactoryやServiceでのクエリ発⾏を原則禁⽌し、クエリ発⾏箇所をRepository に寄せる Repositoryでクエリ発⾏とFactoryの処理を最⼩にするプラクティスを共有。 ORMのEagerLoad機能を使わず、⼿作業で温かみのあるEntityレベルの EagerLoad Nextat Inc.

    68
  69. マスタデータはキャッシュ DBクエリレベルでのキャッシュ → イミュータブルなマスタEntityのキャッシュ へ ローカルのAPCuにキャッシュ デプロイ時にキャッシュのウォームアップ DBクエリ数、キャッシュ取得数を可視化して地道にチューニング Clockwork を拡張した管理画⾯でローカルでも確認できるように

    ORMレベルではなく、Repositoryレベルでのクエリ発⾏元の追跡。 Nextat Inc. 69
  70. 活躍していたClockwork Nextat Inc. 70

  71. 感想と教訓 ベストプラクティスが定まった後の新規実装はとても楽 ドメインから詳細を隠蔽しても開発者がRepositoryの内部を気にする必要はあ る。DBクエリレベルでの最適化も考える ⼀部クエリが散らばっている箇所が残っていて⾟い 何でもかんでも集約しすぎると重い。必要な側⾯だけを抜き出すことの重要性 チューニング結果 この時点で計測不能 → 数秒くらいまでは縮めた

    Nextat Inc. 71
  72. その後、負荷試験チームによる再チューニングにより 無事実⽤レベルへ Nextat Inc. 72

  73. Webフレームワークとの付き合い⽅の変化の話(光?) Nextat Inc. 73

  74. Eloquent (ActiveRecord系ORM)との付き合い⽅ before: Eloquent DBレコードに⾃我が芽⽣えたオブジェクト。はじめにDBありき CRUDくらいしかないアプリならお⼿軽 永続化・クエリの機能とドメインのための機能が⼀つのオブジェクトに混在 規模が⼤きくなってくると、⻑期的に秩序を保ち続けるのは難しい after: Repository

    考え⽅が逆。はじめにEntityありき Entityが永続化される際にデータストアにマッピングされる Repositoryの実装にEloquentが使われるが詳細はドメインからは隔離される Nextat Inc. 74
  75. Eloquentに引きずられていたテーブル設計 before とりあえずauto incrementな整数サロゲートキー after マスタ系:決め打ち整数ID、集約のサブのモデルに対応するテーブルは親のIDを 含む複合主キー 所持系:とりあえずUUIDをバイナリで 永続化前からIDを持つほうが都合が良い Entityとテーブルは必ずしも1:1でなくていい

    Nextat Inc. 75
  76. Controllerの役割の減少 before ソフトウェアの仕事を定める調整役 after ControllerはServiceの⼊出⼒をHTTPリクエスト・レスポンスにマッピングする だけ UIに関係ないServiceまでで⼀連の処理が完結している Nextat Inc. 76

  77. ドメインファースト レイヤを分けたことで、FWに依存するUI、インフラ層抜きでドメイン層だけでテ ストが書けるように ⼀旦データストアのことを忘れてドメインオブジェクトから書き始めていく たまにDBマイグレーションファイルを書き忘れる 我々が設計したインターフェースがたまたまLaravelのコンポーネントを⽤いて実 装されているという感覚 フレームワークと喧嘩しない。フル活⽤は難しいが、必要な機能を Infrastructure・UIに活⽤する。 Nextat

    Inc. 77
  78. DB、UIファーストからドメイン、オブジェクトファ ーストへ フレームワークを活⽤しても、ドメイン層の設計まで は渡さない Nextat Inc. 78

  79. 5. 境界づけ(られなかっ)たコンテキスト (ほぼ闇) Nextat Inc. 79

  80. 境界づけられたコンテキスト 同じモノを対象とした複数の機能において、違う属性を抽出してモデル化したい ケースがある モデルが複数存在するようなケースでは、混乱を防ぐためにスコープを明確化す ることが重要 アプリケーションの⽤途やチームに応じて境界を定め、コンテキスト内でのモデ ルの分裂を防ぐ ex) 輸送アプリケーションにおける予約コンテキストと輸送ネットワークコンテ キスト

    とあるプロジェクト 解決したい問題が根本的に異なる機能でも、共通のモデルで対応していた Nextat Inc. 80
  81. 例1. マスタデータ管理 ゲームの設定の調整を柔軟に⾏うための機能 マスタデータの⼊⼒ミスは結構な確率で起こる ⼊⼒内容のバリデーションが必須 ⼿法は様々 Excel⼊⼒ + 型定義DSLによるバリデーション Googleスプレッドシート管理

    + ⼈の形をしたマスタ管理システム 専⽤のマスタデータ管理画⾯ Nextat Inc. 81
  82. とあるプロジェクトのマスタデータ管理 マスタデータのWeb管理画⾯を作り⼊⼒フォームから更新。ほぼCRUDのみ ⼊⼒したデータはCSVやJSONに出⼒しコードとともにバージョン管理 ゲームAPIと同じドメインオブジェクトを利⽤していた ゲームAPIでは使わないメソッドがドメインオブジェクトに紛れ込んでくる GetterやSetterの追加によるカプセル化の破壊 Repositoryでのページネーション Serviceの依存関係の複雑化 ゲームのEntityとは違う粒度で⼊⼒画⾯を作りたいケース Nextat

    Inc. 82
  83. 対策と反省点 最終的には同じドメインオブジェクトは使ってもServiceを分ける⽅向性に コアドメインではないため省⼒化や分離を検討してもよかった 管理画⾯だけORMを直接利⽤ マスタ管理アプリケーションを分離 データの⼀括⼊⼒に不向きだった。やはり表計算ソフト⽅式が強い CSV⼀括インポートなど補助的な機能も作られた Googleスプレッドシート、Airtableなど既存のシステムの活⽤もやはり有⼒ な選択肢だった Nextat

    Inc. 83
  84. 例2. CS管理画⾯ ユーザの⾏動履歴を確認し問い合わせに対応 or デバッグに活⽤するための機能 CS管理画⾯でしか閲覧しない履歴のために、ゲーム側のServiceに履歴追加処理 が埋められる Nextat Inc. 84

  85. ex) ユーザ所持キャラクターの限界突破の履歴 class BreakLimitUserCharacterService public function breakLimit( PlayerId $playerId, UserCharacterId

    $userCharacterId ) { // ( 略) // 限界突破の処理 $afterUserCharacter = $beforeUserCharacter->breakLimit($materials); $this->userCharacterRepository->save($afterUserCharacter); // 履歴を残す処理 $this->breakLimitHistoryService->add( $beforeUserCharacter, $afterUserCharacter, $materials ); // その他限界突破素材アイテムを消費する処理など } Nextat Inc. 85
  86. ゲームとCS管理画⾯専⽤のアプリケーションの分離も可能だったはず ゲーム本体からCS管理画⾯アプリケーションにイベントで通知 厳密なリアルタイム性が要求されない機能なので結果整合性があれば問題ない Nextat Inc. 86

  87. 6. ちょっと深いモデル(ほぼ光) Nextat Inc. 87

  88. アイテム、装備、キャラクターをユーザに付与する機能 ユーザへのミッションの報酬、バトルのドロップ、ショップ商品購⼊で頻出 プレゼントボックスに送る、直接ユーザの持ち物として付与する 新規⼊⼿かどうかの判定を⾏う ユーザの所持数の上限超過判定を⾏う Nextat Inc. 88

  89. コードの重複 ユーザに付与されるデータ アイテムマスタ + 有効期限 + 数 装備品マスタ + 初期経験値

    + 数 キャラクターマスタ + 初期経験値 + 初期限界突破数 + 数 switchで分岐してそれぞれ処理 あまりに多すぎて実は共通化したほうがいいことに気づく Nextat Inc. 89
  90. ユーザが受け取れるもの、という視点で抽象化 UserReceivableInterfaceと命名、専⽤のServiceを使ってまとめて受け取れるよ うにした 開発者に使い⽅を周知。チーム全員のユビキタス⾔語とまではならなかった。 抽象レベルの改善。クライアントコードではユーザに付与するものがアイテムか 装備品かキャラクターかをほとんどきにする必要がなくなった 重複するコードの排除 Nextat Inc. 90

  91. 軽量DDDを実践した感想とまとめ Nextat Inc. 91

  92. 感想とまとめ ゲームのための設計・インターフェースをFWの機能ありきではない形で考えられ るようになる POPOのクラスを数多く作るとオブジェクト指向に慣れてくる 戦術的パターンをただ適⽤するだけでなく、そのパターンの役割を考えると良い 悩んだことがEvans本を読み返すと書いてある。5章6章あたりだけでも参考にな る。 ゲームはもともとコンピュータのために作られているので開発者と仕様の距離が 近く、モデリングしやすいかも Nextat

    Inc. 92
  93. 軽量DDDも捨てたもんじゃないぞ! Nextat Inc. 93

  94. PR: We're hiring!! Nextat Inc. 94

  95. Nextatではエンジニアを募集中! 最近のメインは業務システム、ECサイト、ソーシャ ルゲームなど ⼀緒に設計について議論してくれる⽅を募集中 Nextat Inc. 95

  96. え、でも京都でしょ? 本社は京都ですが、東京にもオフィスができました 沖縄進出も検討中 Nextat Inc. 96

  97. ご清聴ありがとうございました この後の質疑応答やmeet upでも質問受付 お⼿柔らかに Nextat Inc. 97