世界を動かす技術を、日本語で。

間違った抽象よりも複製を優先する (2016)

2026年6月22日原文(sandimetz.com)

概要

「間違った抽象化」 の問題とその影響について解説。 重複 は「間違った抽象化」よりも安価で安全と主張。 抽象化の失敗 がコードの複雑化や保守性低下を招く流れを説明。 重複の再導入 によるリセットのすすめとその手順を紹介。 99 Bottles of OOP の新刊情報も掲載。

「間違った抽象化」と重複の選択

  • RailsConf 2014 で「重複は間違った抽象化より遥かに安価」と主張
  • 「間違った抽象化より重複を選ぶべき」 というアドバイスが多くの共感を呼ぶ
  • 抽象化の誤用 が業界全体で広く深刻な問題であることを再認識

「間違った抽象化」が生まれる流れ

  • プログラマA が重複を見つけ、抽象化して新たなメソッドやクラスを作成
  • 既存コード が「正しい・必要」と錯覚しやすい心理的圧力
  • 新しい要件 が現れ、既存の抽象化が完全には適合しない状況
  • パラメータ追加や条件分岐 で抽象化を無理やり維持
  • 複雑化と可読性低下 が進行、保守が困難に

サンクコスト効果とその罠

  • 既存コードへの投資 (サンクコスト)が手放しづらさを助長
  • 「これだけ複雑なら重要なはず」 という無意識の思い込み
  • 間違った抽象化 にこだわることで開発効率が大幅に低下

解決策:重複の再導入

  • 抽象化をやめて、各呼び出し元にコードをインライン展開
  • 不要な分岐やパラメータ を削除し、それぞれに必要な処理だけを残す
  • 本来の重複 やパターンが見えやすくなり、再抽象化の判断が容易に
  • 新機能追加や保守 が格段に簡単に

まとめと提言

  • サンクコスト効果 に惑わされず、間違った抽象化は早期に見直すべき
  • パラメータ渡しや条件分岐 が増えたら抽象化の見直しサイン
  • 重複の再導入 は後退ではなく、より良い前進
  • 自身と後続の開発者のためにも、間違った抽象化は積極的に解消

99 Bottles of OOP 新刊情報

  • 99 Bottles of OOP 第2版のリリース
    • 3つの新章 追加、1.5倍のボリューム
    • Ruby, JavaScript, PHP 各言語版を用意
    • epub, kepub, mobi, pdf 各フォーマットで提供
    • 1回の購入で全バージョンのダウンロード権利を付与

Hackerたちの意見

OOPの頃は抽象化に苦労してたけど、ほぼ純粋な関数型アプローチに移ってからは、コードの重複がほとんどなくなったよ。関数を作って、それを2つの部分で呼び出すだけ。メインの抽象化の問題はデータ構造だけど、TypeScriptのインターフェースがダックタイピングみたいなもんだから、そこでもあまり問題にぶつからない。だから、抽象化の問題でコードが重複することは少ないかな。開発者がサイロ化してるせいでのコード重複の方がずっと多いよね。

「2つの部分で関数を呼び出す」って具体的に何?

趣味で関数型言語を使ってるけど、技術が大事だと思ってる。最近の言語は、関数型プログラミング理論に簡単に立つことができるから。Haskellを知らなくても大丈夫。みんなの脳はそれぞれ違うけど、小さくてシンプルで時々柔軟な部分が全体を作るって考え方は、私には合ってる。大きくて複雑なオールインワンの形状とは対照的にね。

開発者は、コードの重複を経験するためにサイロに閉じ込められる必要はないよ。チームの規模がある程度を超えると、各メンバーが他の人が何をやっているかを把握できなくなるから、コードの重複は避けられなくなる。これは、みんなが関数型スタイルのコードを書いていても同じこと。実際、先月職場でこんなことがあったんだ。新しい関数型のヘルパー関数を作ってファイルの最初に置いたんだけど、1週間後に同僚が似たような機能を持つヘルパー関数をファイルの最後に書いたって教えてくれた。

+1 一番最悪なコードのメンテは、DRYを守ろうとして元の意図を理解してないコードだった。あの混乱から抜け出す唯一の方法は、広範なコードの重複だったよ。

記事に同意するけど、両方を経験した人ならわかるよね。過剰に設計されたコードベースより、適切に設計されてないコードベースの方がずっと扱いやすい。

いや、違うよ。これはいつも無駄に反骨的で、賢明な提案とは言えない。少なくとも、間違ったスケールで作業しているときはそうだよ。顧客の数が微妙に多い(5人以上100人未満)と、抽象化してモジュール化すべき重複コードを維持するのは、ジュニアの従業員をどんどん消耗させることを気にしなければ安上がりに見えるだけ。LLMの時代では、間違ったスケールが異なる形で現れる。適切な抽象化なしに生成されて重複したコードが、パターンに出くわすたびに同じ修正をする信頼できないLLMによって維持されるんだ。維持できる抽象化があれば(アクティブにメンテナンスされているものね)、コードの重複よりもずっと良いと言えるよ。

コードの重複は、間違った抽象化より安上がりだよ。良い抽象化があれば、それを使うべき。5人から100人の顧客で良い抽象化が見つからないなら、神の助けを祈るよ。

反骨的とは言えないよ、これはとても理にかなった提案だと思う。常識的な基本アプローチが抽象化から始まるなら反骨的だけど、実際はそうじゃない。常識的なデフォルトは、実際に抽象化するケースがいくつか見つかるまで、重複する可能性のある動作を書くことなんだ。顧客の数が微妙に多い(5人以上100人未満)と、抽象化してモジュール化すべき重複コードを維持するのは、ジュニアの従業員をどんどん消耗させることを気にしなければ安上がりに見えるだけ。間違った抽象化を維持すること、あるいは、神の助けが必要な抽象化を維持するのは、さらに悪化するだろうね。

経験があるみたいだね。ロジックのファクタリングや統一は、十分な歴史があれば気にしないよ。若い開発者が「この2つをマージしなきゃ!」って計画もなしに何度も言ってくると、すごく辛い。クリスタルメーカーみたいにね。そうすると、明らかに問題が出てくる。2つのバリアントはそんなに近くなくて、今や1つの神クラスがすべての力を1つの大きな状態で扱おうとしてる。LLMは自然に抽象に反するマシンだと思うし、逆にする方法を探してることが多いよ。

あなたが良い抽象について説明しているように聞こえる。この記事は、コードの重複がどんな抽象よりも良いとは主張していない。コードの重複が間違った抽象よりも良いと主張しているんだ。おそらくこの著者も、良い抽象がコードの重複よりも良いことには同意すると思う。

過剰設計や「抽象地獄」は、全くもって破壊的な概念ではないよ。

Hacker Newsで議論の続きを見る