開発してるなら一度は聴いたことがあると思う言葉
- DRY
- YAGNI
再利用性VS将来の拡張性
不毛な対立が、今日も何処かで火花を散らしている。
「抽象化しないのは怠慢」
「いや、YAGNIだろ」
この記事では、この手の議論を
正義や美学の話から切り離す。
抽象化とは何か?
この文脈での抽象化の定義なしにこのテーマは語れないので軽く触れる。
ここでいう抽象化とは
抽象化とは、複数の具体的な実装から共通点だけを取り出し、差分を隠すことだ。
- 処理をまとめる
- 使い方を揃える
- 実装の違いを意識させない
これ自体は、ただの手段。
抽象化がもたらすメリット
うまく機能すると、次の効果がある。
- 読むときに考えることが減る
- 修正箇所が一箇所に集まる
- コードの意図が伝わりやすくなる
ここだけ見ると、抽象化は「良いもの」に見える。
抽象化の際に支払うコスト
一方で、抽象化には必ず代償がある。
- 理解するための前提知識が増える
- 裏側の事情が見えなくなる
- 変更時の影響範囲が読みにくくなる
抽象化は、楽になる場面と、重くなる場面を同時に作る。
そのため、抽象化をするという意思決定は軽くあってはならない。
抽象化は「無料」ではない
抽象化にはコストがかかる。
- 抽象構造を考える時間
- 命名に悩む時間
- 実装後の教育コスト
これらはすべて、抽象化により発生する工数だ。
一方で、抽象化によって得られる利益はどうか。
- 将来の変更が楽になる
- 重複修正を避けられる
- 見通しが良くなる
- 依存を切り離しテストの粒度を小さくできる
これはすべて、仮定の未来に属する話だ。
投資っぽくも考えることができる。
抽象化することで、コストを支払い、
不確定な利益を期待できる。
抽象化が「債務」になる瞬間
抽象化が問題になるのは、それが債務に堕ちる時だ。
典型的なパターンを挙げる。
回収計画が存在しない
- いつ使われる想定なのか
- どんな変更を想定しているのか
- それは本当に起きそうなのか
これらが曖昧なまま行われる抽象化は、
回収不能な投資になる。
利息を払う主体が不明
抽象化したコードは、
- 現状把握が難しくなる
- 変更が難しくなる
- レビューするのが大変になる
この「利息」を、誰が払い続けるのかが決まっていないと、
負担はチーム全体に拡散する。
損切りできない
- 抽象化を外す判断ができない
- 外すと壊れそうで触れない
- 書いた人しか理解していない
こうなった時、確実にその抽象化は債務へと変貌する。
DRYとYAGNIは対立していない
よくある誤解として、DRYとYAGNIは対立概念だと主張されてるのを見たことがないだろうか。
実際には、役割が違う。
- DRYは「今ある重複」をどう扱うかの話
- YAGNIは「まだ起きていない未来」をどこまで信じるかの話
問題が起きるのは、
未来の不安を理由に、DRYを先取りで適用したとき。
この瞬間に、抽象化は「利益」ではなく「債務」になる。
工数という現実で考える
ここで一度、感情や思想を捨てて工数だけを見る。
- 抽象化に3日かかった
- 実際に変更が来たのは半年後
- 抽象構造から変更する必要があった
この場合、抽象化は純粋な赤字だ。
一方で、
- 同じ修正が短期間に何度も発生している
- 変更理由が明確に同じ文脈に属している
- 抽象化の境界が説明できる
この場合は、抽象化は利益になりうる。
違いは「考え方」ではなく、観測された事実だ。
YAGNIは「何もしない」ことではない
YAGNIは怠慢ではない。
今は抽象化しない=設計を放棄する
ではない。
それは、設計判断を将来の事実に基づいて行う選択
後からまとめられる重複は、
後からまとめた方が工数効率がいいことも多い。
判断のためのチェックリスト
今やっている抽象化が利益か債務かを判断するために、
最低限これだけは考えたい。
- 回収する変更は具体的に想定できるか
- それは短期間に起きそうか
- 抽象化を外す選択肢は残っているか
- 利息を払う主体は合意されているか
一つでも曖昧なら、その抽象化は債務寄りだ。
抽象化はどんな時でも「善」ではない。
最後に
抽象化は、賢さの証明でも、努力の勲章でもない。
うまい抽象化は将来の利益になり、下手な抽象化は工数を燃やす債務になる。
今やっているその抽象化、いつ元が取れるようになるの?
誰も答えられないなら、それはもう、債務かもしれない。


コメントを残す