■ 1. 主張の概要
- 「複製(duplication)は誤った抽象化よりはるかに安い」という命題を提唱
- 「誤った抽象化よりも複製を選ぶべき」という指針を示す
- この主張はRailsConf 2014での講演「all the little things」で取り上げ、大きな反響を呼んだ
■ 2. 誤った抽象化が生まれるパターン
- プログラマAが重複コードを発見し、抽象化(メソッドまたはクラス)として切り出す
- しばらく時間が経ち、新しい要件が追加される
- プログラマBが既存の抽象化を保持しようとし、パラメータと条件分岐(conditional)を追加して対応する
- さらに新しい要件が来るたびに、別のプログラマが同様の変更を繰り返す
- 結果としてコードは条件分岐だらけの難解な手続きとなり、理解も修正も困難になる
■ 3. 既存コードが及ぼす心理的圧力
- 既存のコードは「正しく、必要なものだ」という強い影響力を持つ
- コードは過去の努力の産物であるため、その価値を保持しようとする動機が生まれる
- コードが複雑であればあるほど「多大な労力をかけたはずだ、無駄にしてはならない」という感覚が強まる
- これは「サンクコストの誤謬(sunk cost fallacy)」に相当し、判断を歪める要因となる
■ 4. 解決策:「前進するための最短路は後退すること」
- 誤った抽象化に直面した場合、サンクコストに引きずられず、後退(巻き戻し)を選ぶべき
- 具体的な手順:
- 抽象化されたコードを、呼び出し元すべてにインライン展開して複製を再導入する
- 各呼び出し元において、渡されているパラメータを基に実際に必要なコードの範囲を特定する
- 各呼び出し元で不要なコードを削除する
- この作業により抽象化と条件分岐の両方が除去され、各呼び出し元は必要なコードだけを保持する
- 旧抽象化を完全に取り除いた後、現行要件に即した形で改めて重複を分離し、新たな抽象化を導出できる
■ 5. 実践的な教訓
- 「この投資を守らなければならない」から「このコードから学べることはすでに学んだ」へ視点を切り替えることで、作業が容易になる
- インライン展開後に前進の道筋が明確になり、新機能の追加が速く容易になる
- パラメータを渡したり、共有コードに条件分岐を追加しているなら、それは抽象化が誤っているサイン
- 誤った抽象化を早期に廃棄するほど、損失は少なくなる
- 後退は撤退ではなく、より良い方向への前進である
■ 6. 付記: 99 Bottles of OOP 第2版リリース
- 99 Bottles of OOP の第2版が新たにリリースされた
- 第2版の変更点:
- 3章追加され、全体量は第1版比で約50%増量
- Ruby、JavaScript、PHP の3言語で個別書籍として提供(内容は同一)
- 「ビール」と「牛乳飲料」の2バリエーションが存在
- epub、kepub、mobi、pdf の4フォーマットで配信
- 合計6種類の書籍、24通りのダウンロード組み合わせ
- 1回の購入でいずれのバージョン・フォーマットもダウンロード可能