目次
1. 機能一覧と詳細説明
2. テーブル設計
3. 工夫した点
4. 振り返り
① 機能一覧と詳細
ユーザー登録 / ログイン
TOPページ
収入 / 収入源
- 収入一覧
- 収入登録 / 編集/ 削除
- 収入源一覧ページ
- 収入源登録 / 編集 / 削除
支出 / 支出カテゴリ
- 支出一覧
- 支出登録 / 編集/ 削除
- カテゴリ一覧ページ
- カテゴリ登録 / 編集/ 削除
② テーブル設計
③ 工夫した点
(1) 収支の計算処理
1. selectRaw と groupBy で、収入と支出のデータをそれぞれ月ごとに集計。
2. pluckを使用し 結果を [month => total] の形式にすることで、特定の月のデータが 参照可能 。
3. for文のループ処理で全12ヶ月分のデータを取得し、存在しない月のデータにはデフォルト値(0)を設定。
(2) DDDに基づく責任分担の明確化
システムの各層(Domain, UseCase, Repository, Infrustructure)に適切な責任を割り当て、役割を明確にすることで、可読性、保守性を向上させる。
(4) 入力データの整合性
- ValueObjectを使用することで、特定の属性に対するバリデーションを行い、不正な値を防ぐ。
- FormRequestを利用して、バリデーションルール(例: password.confirmed や email.unique)を管理し、入力データの一貫性を保持。
④ 振り返り
学んだこと
N+1問題
リファクタ前→各月ごとにIncomesテーブルとSpendingsテーブルへのクエリを実行しているため、12か月分で12×2=24回のクエリが発生。
リファクタ後→各月ごとに実行するのではなく、1年分をまとめて取得 。IncomesとSpendingsそれぞれ1回ずつ(合計2回) のクエリ数で表示。
画像の挿入!!!
結果として、12か月分の収入、支出、収支の集計が効率的に計算され、パフォーマンス の向上。データアクセスの規模が大きくなるにつれ、N+1問題を意識しクエリを最適化すること意識するようにしていきたい。
今後の課題
1. クラスとメソッドの命名規則
リファクタ前では、冗長なプレフィックスやアンダースコアを含む命名があったため、命名の一貫性と可読性の向上が必要。
2. クラスやインターフェース責務の分離
ロジックがUseCase層に集中しており、RepositoryやInfrastructureの役割が活かされていないため、開発規模やロジックの複雑性に応じて、各層を構築できるようにする。
- UseCase層:Repository層やInfrastructure層を利用して必要なデータを取得・保存
- Repository層:データの取得・保存の抽象化
- Infrastructure層:外部システムとの具体的な接続を担当