開発振り返り - 2025年12月6日
開発振り返り - 2025 年 12 月 6 日
総評
今週は「どう実装するか」よりも「なぜその実装を選ぶのか」を考える場面が多かった。既存コードとの統一性、メタプログラミングの是非、テストのしやすさなど、コードの書き方だけでなく設計判断について学びが多い一週間だった。
学んだこと
1. 統一性を取るか、ベストな実装を選ぶか
開発中、新規実装の方法について悩む場面があった。
「本当はこっちの書き方の方がいいと思う。でも既存のやり方と違う。統一性を取るべきか、それとも自分がベストだと思う方法で書くべきか...」
同僚に相談したところ、こんなアドバイスをもらった。
基本的には既存のやり方に沿った方がいい。ただ、影響範囲が小さいなら、自分がベストだと思う実装でやってもいいと思う。
具体的には SQLAlchemy でのクエリ発行の書き方についてだった。
ここから得た学び:
既存との統一性を取るか取らないかは、影響度の大小が判断基準になる。
- 影響範囲が広い → 既存に合わせる(変更コストが高い)
- 影響範囲が狭い → ベストな方法を採用しても OK
「統一性」は目的ではなく手段。保守性を上げるための統一性であって、統一性のために非効率な実装を選ぶのは本末転倒。
2. メタプログラミングの落とし穴
メタプログラミング(コードがコードを生成する手法)について学ぶ機会があった。
便利そうに見えるが、実際には以下のような問題がある。
| 問題点 | 具体的な影響 |
|---|---|
| 動きが見えにくい | どこで何が起きているか追いづらい |
| エラーの原因追跡が困難 | 自動生成されたコードが問題を起こすと、元の原因を特定しにくい |
| 他の人が理解しにくい | 特に経験が浅いメンバーは読み解くのに時間がかかる |
結果として、保守(変更・修正)や調査(不具合の原因追跡)が難しくなる。
教訓:メタプログラミングは「使えるから使う」ではなく、「本当に必要か」を吟味してから採用する。大抵の場合、もっとシンプルな方法で解決できる。
3. テスト対象メソッドの呼び出し方
テストを書くとき、対象のメソッドをリポジトリ経由で呼び出すか、クラス(インスタンス)から直接呼び出すかという違いについて考えた。
# リポジトリ経由
result = repository.some_method()
# インスタンス経由(DIを使用)
instance = SomeClass(dependency)
result = instance.some_method()
インスタンス経由の方が良い理由:
- テストしやすい - 依存関係を差し替えられる(DI: Dependency Injection)
- 結合度が低い - 変更の影響範囲を限定できる
- 一貫性 - プロジェクト内の他の UseCase と同じ書き方になる
「動くコード」ではなく「テストしやすいコード」を意識することで、結果的に保守性も上がる。
4. N+1 問題の回避
ORM を使っていると起きがちな N+1 問題。1 回のクエリで済むはずが、N 件のデータに対して N 回の追加クエリが発生する。
詳細は割愛。
5. 論理削除と物理削除の使い分け
データを削除するとき、本当に DB から消す(物理削除)か、フラグを立てて「削除済み」とする(論理削除)かの判断基準を学んだ。
| 削除方式 | 特徴 | 適したケース |
|---|---|---|
| 物理削除 | DB から完全に消える | 個人情報、一時データ、ログデータ |
| 論理削除 | deleted_at等のフラグで管理 | 復元の可能性がある、監査証跡が必要 |
論理削除を採用する理由:
- データ調査のため - ユーザーの削除有無をデータから追跡できる。「いつ誰が削除したか」を後から確認できるのは運用上大きい
deleted_atを使う利点 - 単純なis_deletedフラグ(Boolean)ではなく、deleted_at(タイムスタンプ)を使えば削除日時も記録できる。NULL なら未削除、値があれば削除済みと判定できて一石二鳥
補足:MySQL の Boolean 型について
MySQL には独立した Boolean 型が存在せず、BOOL/BOOLEANはTINYINT(1)のエイリアス(別名)として扱われる。TRUEは1、FALSEは0に変換される。
論理削除の注意点:
- クエリに常に
WHERE deleted_at IS NULLが必要 - データが増え続けるのでパフォーマンスに注意
- ユニーク制約との兼ね合いが複雑になる
「なんとなく論理削除」ではなく、要件に応じて使い分けることが重要。
まとめ
今週は「どう書くか」より「なぜそう書くか」を考える機会が多かった。
- 統一性 vs ベストな実装 → 影響度で判断
- メタプログラミング → 本当に必要か吟味
- テストの書き方 → DI を意識した設計
- N+1 問題 → Eager Loading で回避
- 削除方式 → 要件に応じて使い分け
コードは書けるようになってきた。次のステップは「なぜその実装を選ぶのか」を言語化できるようになること。来週も設計判断の引き出しを増やしていく。