🐡
「個人開発×Claude Code」ナポレオン開発日記 #3 リファクタリング編
ナポレオン開発日記 #3 — リファクタリング編
こんにちは。前回(#2)で「ゲーム処理全般」の基盤ができたので、今回はそのコードをリファクタリングして保守性高め可読性の高いコードになるよう心がけました。
1. 目的(なぜリファクタリングするのか)
- Reactでの状態管理が入り組んできて読みづらく冗長であった
- 動的importや冗長なロジックでファイルが分かれすぎ、読みづらくなってきた
- 定数やルールがコード中に散在していてルール変更時の影響範囲が大きい
- server actionがほぼ使われていなかった
2. 今回やった主要タスク(一覧)
IMPLEMENTATION_STATUS.mdより抜粋
- 不適切な変数名の修正
- 不必要な処理を削除
- next.jsにおけるuse effectやuse stateなどの使い方の見直し
- next.jsにおけるserver actionを使った実装の設計
- `aiStrategyActions.ts`, `gameInitActions.ts`, `gameLogicActions.ts`, `gameResultActions.ts`
- 文字列リテラル (`'napoleon'`, `'playing'` 等) → 定数参照 (`GAME_PHASES.NAPOLEON`)
- GameActionErrorコード定数化 (`'UNAUTHORIZED'` → `GAME_ACTION_ERROR_CODES.UNAUTHORIZED`)
3. 実際のやりとり(作業の進め方 — 私 / Claude の会話風)
私: Reactの状態管理が適当なので一貫性を持ちたい
Claude: 代表的な3つほどを用いながらリファクタリングします
私: 動的importを禁止してほしい、.mdファイルにルールとして記載してほしい
Claude: 動的importは必要箇所に限定して、エントリで一箇所に集約します。さらに不要なdynamic importは静的 import に戻します。
4. 重要なリファクタリング詳細(抜粋)
4.1 状態管理の改善
大まかに今はこのような構成となっています。
-
GameContext (Context API + useReducer)
- src/contexts/GameContext.tsx - メインの状態管理
- useReducerでゲーム状態を集中管理
- グローバルなゲーム状態を提供
-
カスタムHooksによる責務分離
- useGameActions - ゲームアクション(カード操作、宣言等)
- useGameSubscription - リアルタイム同期(Supabase)
- useGameInitialization - ゲーム初期化ロジック
- useAIProcessing - AI処理
- useSupabase - データベース操作
-
React 19の新機能を活用する
- Transitions - UI更新の優先度制御
- Server Actions - サーバーサイド処理統合
4.2 不要処理の削除・簡素化
- 使われていない関数の削除
- 使われていないパッケージの削除
- 使われていないテストの削除
4.3 定数化(src/lib/constants.ts)
- スート優先順
- 宣言最低枚数
- プレイヤー種別
- ゲーム進行フェーズ
- トランプのA~K
などです。
定数にすることでルールが変わったときの影響範囲が小さくなります。
学び
- 定数参照は指示を具体的に出せばある程度はやってくれた
- ReactおよびNext.jsの状態管理は色んなパターンがあり最適解が難しい
- リファクタリングを通して処理の流れを学べるのはとてもいい
課題
- 指示の出し方が適当だとリファクタリングも適当で時間かかる(当たり前)
- 動作確認とCIのチェックが修正一発では通らないので何度か指示を出したり修正が必要
- せっかくBiomeのLinterがあるのに全然実施してくれない…
まとめ
リファクタリングもある程度出来ました。
ソースコードに対して好奇心を持って引き続きいい実装を心がけて行きます。
リポジトリはこちら 👉 GitHub
Discussion