「便利な関数」が壊れやすい理由
Pythonで書いていると、
何でもやってくれる便利な関数を作りがちです。
- 読み込んで
- 加工して
- 保存して
- ついでにログも出す
一見、使う側は楽です。
ですが、こういう関数ほど、
後から壊れやすくなります。
責任が多いと修正が怖くなる
たとえば、こんな形です。
def process(file):
rows = load_csv(file)
rows = filter_rows(rows)
rows = calculate(rows)
save_csv(rows)
print("done")
この関数は「全部入り」です。
ここに仕様変更が入ると、
どこをどう直せばいいかが曖昧になります。
- 加工だけ変えたい
- 保存形式だけ変えたい
- ログ出力を切り替えたい
変更したい理由が複数ある時点で、
責任が詰まりすぎています。
境界を引き直す
責任を分けると、
見え方が変わります。
def process(file):
rows = load_csv(file)
rows = transform(rows)
save_csv(rows)
def transform(rows):
rows = filter_rows(rows)
rows = calculate(rows)
return rows
「読み込み」「変換」「保存」が分かれただけでも、
修正の範囲が見えるようになります。
境界の目安
関数の境界で迷ったときの目安があります。
- 変更理由が違うものは分ける
- 入力と出力が説明できる単位にする
- 名前で説明できないなら詰め込みすぎ
特に最後が重要で、
名前が process() のままなら、
まだ整理できていない可能性が高いです。
分けすぎ問題は後で考える
ここでよく出る不安が、
「分けすぎて逆に分かりにくくならない?」
というものです。
これは確かに起きます。
ですが多くの場合、
最初に必要なのは「分けすぎ」ではなく、
「詰め込みすぎ」から抜け出すことです。
作って分かったこと
このテーマを通して分かったのは、
- 関数は小ささより責任が大事
- 変更理由が境界を教えてくれる
- 名前は設計の結果
ということです。
おわりに
この話は、
関数と責任の境界を考え直すことで、
修正しやすさが上がった経験を整理した記録です。
次は、
「あとで直す」がなぜ壊れるのか、
時間差で起きる問題を掘ります。


コメント