DDDでポケモンバトルを実装する(Step1：ポケモンをEntityで定義する)

## はじめに
最近、DDDの勉強をしています。DDDを学習する中で、Enitityや値オブジェクト、アグリゲート等の言葉が出てきて、実際にわかったようなわからないようなという状態が続いています。そのため、今回から手を動かして学習していきたいと思っています。サンプルはなんでも良かったのですが、ポケモンバトルを例に今後実装していこうと思っています！！

## 成果物

```shell:ディレクトリ構成
~/develop/pokemon_ddd (feat/step1_pokemon)$ tree -I node_modules 
.
├── biome.jsonc
├── package.json
├── src
│   ├── entities
│   │   ├── Move.ts
│   │   ├── Pokemon.ts
│   │   └── Stats.ts
│   ├── enums
│   │   └── PokemonType.ts
│   └── index.ts
├── tsconfig.json
└── yarn.lock

4 directories, 9 files
```

```shell:実行結果
~/develop/pokemon_ddd (feat/step1_pokemon)$ yarn run exec       
Debugger attached.
yarn run v1.22.19
$ ts-node -r tsconfig-paths/register src/index.ts
Debugger attached.
{ hp: 35, attack: 55, defense: 40, speed: 90 }
[
  Move { name: 'でんきショック', type: 'Electric', power: 40 },
  Move { name: 'でんこうせっか', type: 'Normal', power: 40 },
  Move { name: '10まんボルト', type: 'Electric', power: 90 },
  Move { name: 'アイアンテール', type: 'Steel', power: 100 }
]
Waiting for the debugger to disconnect...
✨  Done in 1.01s.
Waiting for the debugger to disconnect...
```

## プログラム 

```ts:src/entities/Pokemon.ts
import { PokemonType } from "@/enums/PokemonType";
import type { Move } from "@entities/Move";
import { Stats } from "@entities/Stats";

export class Pokemon {
	constructor(
		public readonly id: number,
		public readonly name: string, // ポケモンの名前
		public readonly type: PokemonType[], // ポケモンのタイプ
		private readonly stats: Stats, // ポケモンのステータス
		private readonly moves: Move[], // ポケモンの技
	) {
		if (moves.length > 4) {
			throw new Error("ポケモンは4つまでしか技を持てません。");
		}
	}

	// ステータスを取得するメソッド
	getStats(): Stats {
		return this.stats;
	}

	// 技を取得するメソッド
	getMoves(): Move[] {
		return this.moves;
	}
}
```
:::note info
ポケモンのEntitiyを定義。属性や振る舞いを定義しています。ここでは最低限にしたかったため、名前やタイプ、ステータス、技を初期化しています。
:::

```ts:src/entities/Stats.ts
export interface Stats {
    hp: number;
    attack: number;
    defense: number;
    speed: number;
}
```

```ts:src/entities/Move.ts
import type { PokemonType } from "@enums/PokemonType";

export class Move {
	constructor(
		public readonly name: string,
		public readonly type: PokemonType,
		public readonly power: number,
	) {}
}
```

```ts:src/enums/PokemonType.ts
export enum PokemonType {
    Normal = 'Normal',
    Fire = 'Fire',
    Water = 'Water',
    Grass = 'Grass',
    Electric = 'Electric',
    Ice = 'Ice',
    Fighting = 'Fighting',
    Poison = 'Poison',
    Ground = 'Ground',
    Flying = 'Flying',
    Psychic = 'Psychic',
    Bug = 'Bug',
    Rock = 'Rock',
    Ghost = 'Ghost',
    Dragon = 'Dragon',
    Dark = 'Dark',
    Steel = 'Steel',
    Fairy = 'Fairy',
  }
```

```ts:src/index.ts
import { Move } from "@entities/Move";
import { Pokemon } from "@entities/Pokemon";
import { PokemonType } from "@enums/PokemonType";

// サンプルポケモンの定義
const pikachu = new Pokemon(
	25,
	"ピカチュウ",
	[PokemonType.Electric],
	{
		hp: 35,
		attack: 55,
		defense: 40,
		speed: 90,
	},
	[
		new Move("でんきショック", PokemonType.Electric, 40),
		new Move("でんこうせっか", PokemonType.Normal, 40),
		new Move("10まんボルト", PokemonType.Electric, 90),
		new Move("アイアンテール", PokemonType.Steel, 100),
	],
);

// Pikachuのステータスを表示
console.log(pikachu.getStats());

// Pikachuの技を表示
console.log(pikachu.getMoves());
```