ユースケース駆動開発実践ガイドを参考にシューティングゲーム作成

# 記事概要

[ユースケース駆動開発実践ガイド](https://www.amazon.co.jp/%E3%83%A6%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%82%B9%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E3%83%80%E3%82%B0%E3%83%BB%E3%83%AD%E3%83%BC%E3%82%BC%E3%83%B3%E3%83%90%E3%83%BC%E3%82%B0-ebook/dp/B01B5MX2TC)の内容のまとめと、この本に書かれているプロセスをゆるふわに実践したので、その備忘録を記述していきます。

成果物として作成したのは以下のブラウザで動作するシューティングゲームです。

https://shooting-game-tokyo.netlify.com/

ゲームエンジンにはPixiJSを使用しています。

# 内容ざっとまとめ

>## 第1章 ICONIXプロセス
>
>* UMLよりも軽量なプロセス（そもそも何をするためのもの？）
>
>1. 要求  
>  a. 機能要求  
>  b. ドメインモデリング  
>  c. 振る舞い要求  
>  d. マイルストーン1：要求レビュー
>2. 分析/予備レビュー  
>  a. ロバストネス分析  
>  b. ドメインモデルの更新  
>  c. コントローラーの命名  
>3. マイルストーン2：予備設計レビュー（PDR）
>4. 詳細設計  
>  a. シーケンス図の作成   
>  b. ドメインモデルの更新  
>  c. 静的モデルの整理  
>5. マイルストーン3：詳細設計レビュー（CDR）
>6. 実装
>  a. コーディングと単体テスト  
>  b. 統合テストとシナリオテスト  
>  c. コードレビューとモデルの更新  
>
>
>という流れで、ICONIXプロセスは進んでいくらしいです。それぞれが大まかにどんなものかをこの章では説明しています。
>
># 第1部 要求定義
>
>## 第2章ドメインモデリング
>ドメインモデリングについて取り扱う章。
>ドメインモデリングの目的は、問題領域に対する共通の用語集を作成することによって、プロジェクトのコミュニケーションミスによる問題を解決することにある。
>
>### 2.1 上空3000メートルからの眺め
>ユースケースより早期に着手する理由は、ドメインモデルにより定義された用語でユースケースは描かれるべきだから。まぁ諸説あるらしいが、筆者はこうするらしい。
>
>### 2.2 ドメインモデリングの理論
>
>原則のトップ10は以下のよう
>
>* 現実世界（問題領域）のオブジェクトに焦点を合わせなさい。
>* オブジェクト同士の関係を表現するため、汎化（is-a）関係および集約（has-a）関係を利用しなさい。
>* 最初のドメインモデリングにかける時間は2時間に限定しなさい。
>* 問題領域中の主要な概念を中心にクラスを構成しなさい。
>* ドメインモデルをデータモデルと勘違いしてはいけません。
>* オブジェクト（単一のインスタンスを表現する存在）とデータベースのテーブル（モノの集合を含む存在）とを混同してはいけません。
>* ドメインモデルをプロジェクトの用語集として使いなさい。
>* 名前が曖昧になることを避けるため、ユースケースを書く前にドメインモデルを書きなさい。
>* 最終的なクラス図が、ドメインモデルと正確に合致することを期待してはいけません。しかしこの2つは、何らかの形で相似の関係にあるはずです。
>* ドメインモデルには、画面やその他のGUI固有の部品クラスを配置してはいけません。
>
>
>## 第3章 ユースケースモデリング
>ユースケースは「ユーザーがこのシステムで何をしたいのか？」「ユーザーは何を得たいのか？」といった、基本的な疑問を答える助けとなる。
>
>### 3.2 ユースケースモデリングの理論
>
>作成後に設計が可能となるようなユースケースを記述せねばならない。つまり、ユースケースとクラスには密接な関係がある。
>
>原則のトップ10は以下のよう
>
>* 2段落ルールに従いなさい。  
>  * ユースケース記述は「基本フロー」と「代替フロー」の2段落で表現する。   
>* アクターとユースケース図を使ってユースケースを組織化しなさい。
>* ユースケースは叙述的に書きなさい。
>* イベントとその応答の流れとしてユースケースを書き、ユーザーとシステムの対話の両側を記述しなさい。
>* GUIプロトタイプや画面モックアップを使いなさい。
>* ユースケースは実行時の振る舞いの仕様であるということを忘れないように。
>* オブジェクトモデルの言葉を使ってユースケースを書きなさい。
>* 「名詞-名詞-動詞」という文の構造にしたがってユースケースを書きなさい。
>* ドメインクラスの名前を使いなさい。
>* （画面のような）バウンダリクラスの名前を使いなさい。
>
>---
>* includesやextendsなど、どの関係を使うか悩むのはナンセンス。
>* ユースケース記述の詳細なテンプレートを作ることに関して、諸説あるらしいが、この本では反対の立場をとっている。理由としては、時間が無駄にかかり、本質部分を考えずフォームを埋めることに終始することになる傾向があるため。　
>
>## 第4章 要求レビュー
>      
>### 4.1 要求レビューの理論
>
>原則のトップ10は以下のよう。
>
>* 問題領域における最も重要な概念（現実のオブジェクトなど）の少なくとも80%が、エンドユーザーにも理解できるように技術的な言葉を使わずにドメインモデルに記述されていることを確認しなさい。
>* ドメインモデルが、ドメインオブジェクト間のis-a（汎化）関係やhas-a（集約）関係を示していることを確認しなさい。
>* ユースケースの基本コースと代替コースの双方を叙述的に記述していることを確認しなさい。
>* 機能要求のリスト（「～しなければならない」という記述）がある場合、それが叙述的なユースケース記述中に紛れ込んでいたり、テキストを「ぐちゃぐちゃに」していたりといったことがないことを確認しなさい。
>* ユースケースがパッケージによって組織化され、かつ各パッケージには最低一つのユースケース図が含まれていることを確認しなさい。
>* ユースケースがオブジェクトモデルの用語で記述されていることを確認しなさい。
>* ユースケースはユーザーインターフェースの用語で記述しなさい。
>* ユースケース記述にはGUI紙芝居、線図、画面モックアップあるいはGUIプロトタイプを付随させなさい。
>* ユースケース、ドメインモデル、画面モックアップ/GUIプロトタイプを、エンドユーザー、ステークホルダー、販売担当者、技術担当メンバーと一緒にレビューしなさい。
>* レビューを「より良いユースケースのための8つの簡単なステップ」に沿って構成しなさい。
>
>---
>
># 第2部 分析/概念設計/テクニカルアーキテクチャ
>
>## 第5章 ロバストネス分析
>
>### 5.1 上空3000メートルからの眺め
>
>* ロバストネス図を書くにあたっては登場人物が3つ出てくる。
>![object_oriented06_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105281/7a3b8b3c-bd28-6e49-c9ed-420eea8a21b7.png)
>* バウンダリ、エンティティは名詞（オブジェクト）で、コントローラーは動詞（処理）である。  
>    * 名詞と動詞はつなぐことができる。
>    * 名詞を他の名詞とつなぐことはできない。
>    * 動詞と他の動詞をつなぐことはできる。
>
>### 5.2 ロバストネス分析の理論
>原則のトップ10は以下のよう。
>
>* ユースケース記述をロバストネス図に直接貼り付けなさい。
>* ドメインモデルからエンティティクラスを取り出し、不足しているものがあれば追加しなさい。
>* ロバストネス図の作成中にも、ユースケース記述を書きなおして明確にすることがあります。
>* 画面単位にバウンダリオブジェクトを作成し、明確な画面名を付けてください。
>* コントローラは、本物のコントロールオブジェクトになることがあるかもしれないということを忘れないでください。これらは通常、論理的なソフトウェア機能にすぎません。
>* ロバストネス図上の矢印の方向について気にしてはいけません。
>* 親のユースケースから起動されるのであれば、ユースケースをロバストネス図上にドラッグしてもかまいません。
>* ロバストネス図はユースケースに対する予備的な概念設計をしめしています。文字通りの詳細設計ではありません。
>* 一般的に、ロバストネス図上のバウンダリオブジェクトとエンティティクラスはシーケンス図上のオブジェクトインスタンスとなります。一方、コントローラーはシーケンス図上のメッセージとなります。
>* ロバストネス図はユースケースの「オブジェクトの絵」であるということを忘れないでください。その目的はユースケース記述とオブジェクトモデルの両方を強制的に洗練させることです。
>
>---
>* 個別のGUI部品をロバストネス図に書くのは控える。すべての部品を入れるのは大変であるため。
>
>## 第6章 予備設計レビュー
>
>### 6.1　予備設計レビューの理論
>
>#### なぜ予備設計レビューを行うのか？
>
>* why:ロバストネス図、ドメインモデル、ユースケース記述の整合性が取れていることを確認する。
>* who:顧客の代表者、開発チーム、プロジェクトに深く関わっているマネージャーが参加する。
>* what:整合性の確認のほかに、エンティティクラスに属性を追加し、システムの全画面に名前を付け、画面とエンティティクラス間のデータの流れを確実に追跡可能となるようにする。
>
>#### 予備設計レビューガイドラインのトップ10
>
>* ユースケースごとに、ユースケース記述とロバストネス図が一致しているかどうかを蛍光ペンを使って確認しなさい。
>    * 不整合発見のため   
>* ロバストネス図上のすべてのエンティティが、更新後のドメインモデル上に確実に存在するようにしなさい。
>* エンティティクラスと画面の間で、データのながれを確実に追跡できるようにしなさい。
>* 代替コースが漏れていないか、そして見つけ出したすべての代替コースに対する振る舞いが記述されているか確認しなさい。
>* 各ユースケースが、確実にユーザーとシステムの間の対話の両側をカバーするようにしなさい。
>* ロバストネス図の構文ルールを破っていないことを確認しなさい。
>* 技術者以外（顧客やマーケティングチームなど）と技術者（プログラマ）の双方が確実にレビューに参加するようにしなさい。
>* ユースケースがオブジェクトモデルとGUIの用語で記述されていることを確認しなさい。　
>* ロバストネス図（と対応するユースケース記述）でシーケンス図上に表現するようなレベルの詳細を示そうとしていないことを確認しなさい（詳細設計にはまだ手をつけてはいけません）。
>* より良い予備設計のための「6つの簡単な手順」に従いなさい。
>    * 図がユースケース記述に合致しているかどうかを確認する。
>    * 図がロバストネス図の規則に従っているかどうかを確認する。
>    * 図がユースケースの論理的な流れに注力しているかどうかを確認する。　
>    * ユースケースの動作に必要となるすべての代替コースが、図に示されているかどうかを確認する。
>    * 図が「デザインパターン狂」になっていないかどうかを調べる。
>    * 図が詳細設計に踏み込んでいないかどうかを確認する。
>
>## 第7章 テクニカルアーキテクチャ
>
>このステップでの目的は、開発しようとするシステムの全体観をつかむことにある。
>
>### 7.1 上空3000メートルからの眺め
>
>テクニカルアーキテクチャはロバストネス分析中からしっかりと考え始めるべき。
>ロバストネス分析が完了したらテクニカルアーキテクチャも完了させねばならない。
>テクニカルアーキテクチャは詳細設定開始前には**確実に**確定させねばならない。
>
>
>### 7.2 テクニカルアーキテクチャの理論
>
>ガイドライントップ10
>
>* 機能、データ、システムに対する個々のアーキテクチャを分離しなさい。
>* アーキテクチャを構築する理由を理解しなさい。
>* 要求に基づいてアーキテクチャの目的を決定しなさい。
>* スケーラビリティ、セキュリティ、可用性といった要素について考慮しなさい。
>* 国際化（internationalization）および地域化（localization）について考慮しなさい。
>* 困難な問題は関係者全員に提示しなさい。
>* 必要な答えが得られなければ、再度質問してください。
>* テスト容易性について考慮しなさい。
>* 連携しなければならない外部システムについて調査しなさい。
>* アーキテクチャが正しいと信じる勇気、そしてプロジェクトの間を通じてアーキテクチャの決定を推進する強さを持ちなさい。
>
>---
>
>SpringのdispatcherServletなど（Webブラウザからリクエストを受け取り、実際のビューを生成する処理をJSPに委譲する存在）をどのコンポーネントに配置すべきか、といった議論はあまり価値を生まないのでとりあえずどこかにおいておけばよい。
>
>### 7.5 テクニカルアーキテクチャにおける失敗のトップ10（「やってはいけない」）
>
>* ハードウェアのコストや、新しいハードウェアについて考えずに、アーキテクチャを選択する。
>* 「いつもこの方法でやれてきたから」という理由で、先祖伝来のアーキテクチャを利用する。
>* スケーラビリティについて考慮しない。
>* セキュリティについて考慮しない。
>* 市場がそっちを向いているからといった理由で（でもその技術についてはよくしらないにもかかわらず）、新しい技術（言語、プラットフォーム、フレームワーク）を選択する。
>* プロジェクトの要求に基づいて、テクニカルアーキテクチャの目的を明確化することに失敗する。
>* 設計に入る前に、アーキテクチャに長い時間をかけすぎる。
>* システムをテストする方法について考慮するのを忘れる。
>* ユーザーが必要としていることを理解する前にテクニカルアーキテクチャを定義する。
>* アーキテクチャの構築を一切行わない。
>
># 第3部 設計/コーディング
>
>## 第8章 シーケンス図
>
>この局面にまでにテクニカルアーキテクチャは確定している必要がある。
>
>### 8.1 上空3000メートルからの眺め  
>
>シーケンス図はひとつのユースケースごとに存在する。
>
>シーケンス図において、コントローラーオブジェクトはバウンダリオブジェクトとエンティティオブジェクトのメッセージとなる。
>
>活性区間は表示しないようにすべき。
>
>### 8.2 シーケンス図作成の理論
>
>ガイドライントップ10は以下。
>
>* 最大限の効果を得るため、なぜシーケンス図を描くのか理解しなさい。
>    * クラスに対する責務の割り当て
>    * ユースケースの生存期間中に、各クラスが他のクラスとどのように相互作用するかの提示
>    * クラスに対する操作の割り当ての完了
>* すべてのユースケースに対して、基本コースと代替コースの両方のシーケンス図を、同じ図上に記述しなさい。
>* シーケンス図の作成は、バウンダリクラス、エンティティクラス、アクター、そしてロバストネス分析の結果を反映したユースケース記述から始めなさい。
>* シーケンス図は、ユースケースの振る舞い（すなわち、ロバストネス図上のすべてのコントローラー）をオブジェクトがどのように達成するかを示す道具として使いなさい。
>* ユースケース記述が、シーケンス図上でやり取りされるメッセージと対応付けられるかどうかを確認しなさい。記述とメッセージのやり取りとを並べてみるとよいでしょう。
>* 活性区間（focus of control)対する検討に、長い時間を費やしてはいけません。
>* メッセージを描くことによって操作をクラスに割当なさい。多くのモデリングツールはこの機能をサポートしています。
>* すべての操作が正しいクラスに割り当てられるように、操作の割り当てを行っている間はクラス図を繰り返しレビューしなさい。
>* コーディングを始める前に、シーケンス図上に描かれた設計をプレファクタリングしなさい。
>* 詳細設計レビューを行う前に、静的モデルを整理しなさい。
>
>----
>
>#### どのようにしてシーケンス図を作成するか：必要不可欠な4つのステップ
>
>最初の3つのステップはほとんど自動的に行える作業で、4番目の作業が肝。
>
>1. ユースケース記述をそのままシーケンス図に張り付ける
>2. ロバストネス図からエンティティオブジェクトをコピーする
>3. ロバストネス図からバウンダリオブジェクトとアクターをコピーする
>4. クラス操作を割り当てる
>
>
>
>## 第9章 詳細設計レビュー
>
>### 9.1 上空3000メートルからの眺め
>
>#### なぜ詳細設計レビューを実施するのか？
>以下の3点のゴールが達成しやすくなるため。
>
>* 詳細設計での「どのようにして（How）」が、要求で定義された「何を（What）」に確実に合致するようになる。
>* 設計の品質をレビューする。設計のエキスパートが1名いると良い。
>* メッセージの一貫性をチェックする。
>
>#### 誰が詳細設計レビューに参加すべきなのか？
>設計者と開発者。技術に明るい人が参加する。
>
>#### 詳細設計レビューをするのに適したタイミングは？
>シーケンス図、クラス図の完成後。
>
>### 9.2 詳細設計レビューの理論
>
>トップ10
>
>* シーケンス図がユースケース記述に合致していることを確認しなさい。
>* 個々のシーケンス図が基本コースと代替コースの両方をカバーしていることを確認しなさい。
>* 操作が適切なクラスに割り当てられていることを確認しなさい。
>* クラス図上のクラスに、適切な属性と操作が割り当てられていることを確認しなさい。
>* 設計にパターンやその他の詳細な実装上の構造が適用されているのであれば、それらがシーケンス図にも反映されていることを確認しなさい。
>* 機能要求が全てカバーされていることを確かめるため、それらの要求をユースケースおよびクラス上で追跡しなさい。
>* プログラマたちが設計を「しっかりとチェックした」かどうか、そしてその設計でシステムを構築でき、かつ期待通りに動作することに自身を持っているかどうかを確認しなさい。
>* すべての属性が正しく記述されており、操作の返却値と引数リストが完全かつ正確であることを確認しなさい。
>* クラスに対するコードの雛形を生成し、厳密に精査しなさい。
>* リリースに対するテスト計画をレビューしなさい。
>
>

---

# 作ってみたもの

途中でメンテしなくなったので、成果物間の整合性はとれていないです。

## 要求定義

ICONIXプロセスで定義されている成果物ではないかもしれませんが、どんなものを作るか簡単に書きました。

># ゲーム制作
>
>#### スタート画面
>* プレイヤーはスタート画面からハイスコアトップ3を確認することができる。
>  * トップ3のプレイヤー名、スコアが表示される
>  * トップ3のプレイヤーが存在しない場合 - で表示される
>* プレイヤーはスタートボタンを押下することでゲームを開始することができる
>
>#### ゲーム中
>
>##### 自機
>* 自機は十字キーもしくはWASDを入力することで移動することができる
>* 自機は前方向に対して一定間隔で自機弾を発射する
>* 自機弾が敵に命中した場合、敵のHPを減少させる
>* 自機に敵機の弾が衝突した場合、残機を減少させる
>* 残機が0になった時、ゲームオーバーとなる。
>
>##### 敵機
>* 一定時間ごとに、敵機が上から現れてくる。
>* 敵はランダム、ゲーム時間で選ばれた行動パターンに従って行動する
>  * 行動パターンは、移動速度、移動ルート、弾の発射間隔、弾の発射方向、弾の発射速度を持つ
>  * 敵機は行動パターンに従って弾を発射する
>    * 敵機の弾が自機に衝突した場合、自機の残機を減少させる
>* 敵機に自機弾が衝突した場合、HPを減少させる
>  * 敵機のHPが0を下回った場合、敵機は画面から消滅する。
>	* 敵機が消滅した時、敵機に紐づいたスコアが加算される
>* 敵機から発射された弾が自機に当たった場合、ダメージを受ける
>* 敵が画面下部に到達した場合、消滅する。ただし、スコアは加算されない
>
>
>##### その他
>* ゲーム中、残機、スコアを確認することができる
>* ゲームオーバになった時、スコア確認画面に遷移する
>
>#### スコア確認画面
>* スコア確認画面からスコアを確認することができる
>* プレイヤー名を入力した後、送信ボタンを押下することで結果(スコア、プレイヤー名)を送信することができる
>* 結果送信時、戻るボタン押下時にスタート画面に戻る
>
>## ドメイン整理前
>
>HP
>ゲームオーバー
>ゲーム時間
>スコア
>スコア
>スコア確認画面
>スタートボタン
>スタート画面
>ダメージを受ける
>ハイスコアトップ3
>プレイヤー
>プレイヤー名
>十字キー
>命中する
>弾の発射方向
>弾の発射速度
>弾の発射間隔
>戻るボタン
>敵機
>残機
>消滅する
>画面下部
>発射する
>移動
>移動ルート
>移動速度
>結果
>自機
>自機弾
>行動パターン
>送信ボタン

## ドメインモデリング

![DomainModeling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/058853a2-c3dc-3582-fa74-d8b18f47f16c.png)

## ユースケース、ロバストネス図 

ちょこちょこ実現できてない機能がある。。

![robustness.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/f8640525-5a8e-aed0-1425-195bd7edb2aa.png)

## シーケンス図

なし！

## クラス図

![playing game.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/12154b09-83c6-6fa4-eacf-98074625c626.png)

# 感想

ICONIXプロセスの良さはイマイチわかりませんでした。
まぁ教科書通りにやっていないし、作成したものの仕様も複雑ではないので当然っちゃ当然かもしれませんが。
本を読んでいる中で、お客さんとかと合意を取るプロセスでICONIXプロセスで定義されている成果物を一緒に見ることができれば、目的とするもののズレは少なくなるかもなぁ、とは感じました。

個人的にはクラス図を書いていると何か生み出している感があって楽しかったです。笑

# コードやクラス図などなどの置き場

https://github.com/tokyo-forest/shooting-ddd
https://github.com/tokyo-forest/shooting-game