ミノ駆動本を読んでクソゲーを神ゲーにリファクタしてみた

# はじめに
本記事は[ミノ駆動本を読んでクソゲー作ってみた](https://qiita.com/KeiFunahashi/items/eb42d9de6290a01722df)の続きです。
上記記事の内容のクソゲーでは、同じ条件文が複数のクラスに存在していたことが原因で機能追加時に処理が漏れてバグっていました。
この悪魔を退治する方法はクラスの責務をハッキリさせて、処理をかくべき場所をハッキリさせてあげることかと思います。
今回はあのクソゲーを神ゲーにするため、悪いコードの課題の検証をして改善するためのモデリングをしてリファクタしていきます。

※ 神ゲー = 保守運用しやすく、バグが発生しにくいゲーム


### 身に付くスキル
- 保守や変更がしやすいコードを書くための考え方

# 参考資料
[仙塲 大也. 良いコード／悪いコードで学ぶ設計入門保守しやすい　成長し続けるコードの書き方](https://www.amazon.co.jp/dp/B09Y1MWK9N/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

# 内容
今回作成したゲームの実際のコードになります。
https://github.com/kdr250/good-code-bad-code-sample

### 前回のコードの課題   
- 前回の悪いコード編の課題はモデリング全くしてなかった。その結果、凝集度の低いコード設計になってしまっていて、運用時に修正漏れが発生しやすくなってしまっていた。

- とりあえずどんな処理でもかけるなんでもクラスが存在していた。([UIクラス](https://github.com/kdr250/good-code-bad-code-sample/blob/main/bad/src/main/java/com/example/sample/UI.java))

### モデリングとは

>動作原理やしくみを簡単に理解・説明するために、物事の特徴や関係性を図式化したものをモデル、モデルをつくる活動をモデリングと呼びます。

上記は、13章の冒頭に記載されている内容になります。
`動作原理やしくみを簡単に理解・説明するために、物事の特徴や関係性を図式化したもの`をもう少し具体的にしてみます。



### 悪いコードの設計
悪いコードの課題の検証するためにクラス図を用いて状態をイメージしていきます。
#### クラス図
![悪いコードのクラス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708735/ed2088e9-57a5-56af-23cb-91309b99b3b2.png)


[MagicManagerクラス](https://github.com/kdr250/good-code-bad-code-sample/blob/main/bad/src/main/java/com/example/sample/MagicManager.java)は存在していたが、各メソッドの中でそれぞれ技ごとに条件分岐をしてそれぞれの値を返す構造になっていました。
そのため、処理自体が`UIクラス`の`attackPower`メソッドの中でダメージを計算するために条件分岐をしなけなばならなくなっていました。

結果として、それぞれのクラスの中で各技の処理が必要になり、複数箇所に条件分岐が存在して条件文の追加漏れが発生してしまいました。

### 良いコードの設計

#### 課題解決のための分析仮説

悪いコードから良いコードにリファクタする改善ポイントを２点具体的に考えました。
- `MagicManagerクラス`の各メソッドの中でそれぞれ技毎に条件分岐してそれぞれの値を返す構造になっている点。
- `UIクラス`の中でdamageがプリミティブ型として処理されている点。

上記を踏まえ、モデリングをしていきます。

#### モデリング
![サンプルRPG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708735/451e649f-5ae6-b602-66ac-e30b364ffd1c.png)

モデリングして大きく変わった点
- それぞれの技を各モデルとして定義しました。
- 攻撃力を定義し、ヒットポイントで与えるダメージをモデルとして定義しました。

#### クラス図
![サンプルRPG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708735/6e5f3f12-1572-7942-b4ac-b1d603cca9f8.png)

モデリングした内容をに合わせてリファクタした実装のクラス図です。
それぞれの技をエンティティとして扱うことで条件分岐をする必要がなくなりました。
また、Damageクラスを定義したことでHitPointとして与えるダメージが型安全になりました。
ダメージの計算自体は[PlayerBattleStatus.totalAttackPower()](https://github.com/kdr250/good-code-bad-code-sample/blob/fdbad16e080f44a2509c5edf33f234087f8b0fc6/good/src/main/java/com/example/sample/domain/model/battle/PlayerBattleStatus.java#L106)に実装しています。
実際にダメージを与える処理は[PlayerDomainService.attackEnemy()](https://github.com/kdr250/good-code-bad-code-sample/blob/fdbad16e080f44a2509c5edf33f234087f8b0fc6/good/src/main/java/com/example/sample/application/service/player/PlayerDomainService.java#L42)で定義しています。

# 期待した効果が得られたか
モデリングをしたことで必要なモデルが整理されたためクラスの目的がハッキリし、処理やプロパティが整理されたことで、どこにどういった処理が書かれているかわかりやすくなりました。
その結果、凝集度が高い設計になり、仕様変更時に処理の追加漏れを防ぎやすくなったのと同時にコードが読みやすくなり、新規参画者の実装理解しやすい神設計に生まれかわりました。

# その後...

![good_code_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708735/27ee87f3-b92c-5461-0cee-5fb04766ac01.gif)

◯◯ ）PMさん！新しい技を追加完了しました！

PM ) お！ありがとう！

◯◯ ）ついでにいい感じにコードをリファクタしておきました！

PM ）さすがだねぇ、君みたいなエンジニアがいてくれると助かるよ！頼りにしてる！

◯◯ ）😤（ドヤ）

# おわりに
今回は
- 13章 モデリング - クラス設計の土台 -

をピックアップして実際にリファクタリングすることで悪いコードが発生させる悪夢の退治方法の一部を紹介していきました。
あるべき構造を理解して実装やリファクタしていくことで、悪魔のいない世界になることを願っています。