NINOMIN BLOG

開発振り返り - 2025年12月6日

8 min read
reflection
learning
development
Python
SQLAlchemy

開発振り返り - 2025 年 12 月 6 日

総評

今週は「どう実装するか」よりも「なぜその実装を選ぶのか」を考える場面が多かった。既存コードとの統一性、メタプログラミングの是非、テストのしやすさなど、コードの書き方だけでなく設計判断について学びが多い一週間だった。


学んだこと

1. 統一性を取るか、ベストな実装を選ぶか

開発中、新規実装の方法について悩む場面があった。

「本当はこっちの書き方の方がいいと思う。でも既存のやり方と違う。統一性を取るべきか、それとも自分がベストだと思う方法で書くべきか...」

同僚に相談したところ、こんなアドバイスをもらった。

基本的には既存のやり方に沿った方がいい。ただ、影響範囲が小さいなら、自分がベストだと思う実装でやってもいいと思う。

具体的には SQLAlchemy でのクエリ発行の書き方についてだった。

ここから得た学び

既存との統一性を取るか取らないかは、影響度の大小が判断基準になる。

  • 影響範囲が広い → 既存に合わせる(変更コストが高い)
  • 影響範囲が狭い → ベストな方法を採用しても OK

「統一性」は目的ではなく手段。保守性を上げるための統一性であって、統一性のために非効率な実装を選ぶのは本末転倒。


2. メタプログラミングの落とし穴

メタプログラミング(コードがコードを生成する手法)について学ぶ機会があった。

便利そうに見えるが、実際には以下のような問題がある。

問題点具体的な影響
動きが見えにくいどこで何が起きているか追いづらい
エラーの原因追跡が困難自動生成されたコードが問題を起こすと、元の原因を特定しにくい
他の人が理解しにくい特に経験が浅いメンバーは読み解くのに時間がかかる

結果として、保守(変更・修正)や調査(不具合の原因追跡)が難しくなる

教訓:メタプログラミングは「使えるから使う」ではなく、「本当に必要か」を吟味してから採用する。大抵の場合、もっとシンプルな方法で解決できる。


3. テスト対象メソッドの呼び出し方

テストを書くとき、対象のメソッドをリポジトリ経由で呼び出すかクラス(インスタンス)から直接呼び出すかという違いについて考えた。

python
# リポジトリ経由
result = repository.some_method()

# インスタンス経由(DIを使用)
instance = SomeClass(dependency)
result = instance.some_method()

インスタンス経由の方が良い理由

  1. テストしやすい - 依存関係を差し替えられる(DI: Dependency Injection)
  2. 結合度が低い - 変更の影響範囲を限定できる
  3. 一貫性 - プロジェクト内の他の 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/BOOLEANTINYINT(1)のエイリアス(別名)として扱われる。TRUE1FALSE0に変換される。

論理削除の注意点

  • クエリに常にWHERE deleted_at IS NULLが必要
  • データが増え続けるのでパフォーマンスに注意
  • ユニーク制約との兼ね合いが複雑になる

「なんとなく論理削除」ではなく、要件に応じて使い分けることが重要。


まとめ

今週は「どう書くか」より「なぜそう書くか」を考える機会が多かった。

  • 統一性 vs ベストな実装 → 影響度で判断
  • メタプログラミング → 本当に必要か吟味
  • テストの書き方 → DI を意識した設計
  • N+1 問題 → Eager Loading で回避
  • 削除方式 → 要件に応じて使い分け

コードは書けるようになってきた。次のステップは「なぜその実装を選ぶのか」を言語化できるようになること。来週も設計判断の引き出しを増やしていく。