Robert C. Martin先生のCleanCode第12章を読んだメモ。

創発(第12章)の概要

  • 創発的設計を通して、洗練する
    • ケントベックによる優れた設計を生み出すことが可能となる単純な4つの規則(重要順)
      • 全テストを実行する。
      • 重複がない
      • プログラマの意図が表現されている。
      • クラスとメソッドを最小化する。
    • これに従えば、以下が得られる。
      • コードの構造と設計に対する洞察。
      • SRPやDIPのような原則を簡単に適用できる。
  • 単純な設計への規則1: 全テストを実行する
    • 単体テストを書け。
    • 単体テストが書けるようにすることで、単一機能を実装しているような設計へと促される。
    • 物事をテストが簡単になる方向へ推し進めることができる。
    • 強い結びつきがあるとテストが困難になるので、必然的にDIPや依存性注入のようなツールなどで結びつきが最小限になっていく。
  • 単純な設計への規則2〜4: リファクタリング
    • テストができれば気軽にリファクタできるようになる。
    • リファクタリングで以下をシステムに与える
      • 凝集性を高める
      • 結合を弱める。
      • 関心ごとを分離
      • システムの関心ごとをモジュール化
      • 関数とクラスを小さくする
      • より良い名前を考える。
      • 重複の排除
      • 表現力の保証
      • クラスとメソッド数の最小化
  • 重複の排除
    • 優れたシステムの最大の敵は重複
    • 余計な作業や、余分な危険、不必要な複雑さをもたらす。
    • 例えば、isEmptyメソッドとsizeメソッドを持つCollectionクラスがあった場合、isEmptyメソッドでsizeメソッドを使うことで、量を取得するロジックをsizeに共通化できるなど。
    • 小さな再利用ががシステムの複雑さを大きく減少させることになる。
    • 大きな再利用を実現するには、小さな再利用を理解することが肝
  • 表現に富む
    • 自分自身が理解できるコードを書くのは簡単。
    • 保守する人たちに、深い理解を期待することはできない。
    • ソフトウェアプロジェクトの大半は保守コスト
    • 良い命名と、驚き最小の原則、関数とクラスを小さく保つkとおで実現できる。
    • 標準の用語を用いることでも表現しやすくなる。
    • デザインパターンの名前をそのままクラスに当てることで他の開発者に意図を伝えるのもあり。
    • 適切に記述された単体テストでも表現できる。
    • 最も重要なのは、「試す」こと。
      • コードが書けたら、次に読む人にとって分かり易コードか、想像力を働かせる。
      • 自分の書いた関数とクラスに少しだけ時間を割いて、良い名前と関数の分割に注意を払う。
  • クラスとメソッドを最小限に
    • 重複の排除、コードの表現力、SRPといった基本的な概念は行き過ぎてしまう場合もある。
    • クラスとメソッドを小さくしようとすれば、小さなクラスとメソッドがあまりに多く生成されてしまう。
    • クラスとメソッドが多すぎる状況は、名器な独断の結果から生じている可能性がある。
    • 全てのクラスにインターフェースの作成を強要するようなコーディング標準や、フィールドの振る舞いとデータクラスと振る舞いクラスとを常に分けることを強制することは避けた方が良い。
    • 目的は、システム全体を小さくしつつ、関数とクラスも小さくするということ。
    • ただし、優先順位は、規則の中でも最も低いということが重要。
    • テストや、DRY、コードの意図の表現の方が重要。
  • 結論
    • 経験にとってかわる実践手法は存在しない。
    • 通常なら、習得に何年も要するが、上記の規則でそれを促進することができる。

感じたこと

重要順以外は概ね同意すると感じた。
個人的には、重複の削除は2番目に来るほど重要ではない。
過度な共通化は地獄を見ると思う。
そのため、その共通化は本当に必要なのかの判断する目がとても大切になると感じている。

  • 将来的に共通化した処理が異なる可能性が低いのか。
  • 処理は一緒だが、概念は異なるのではないか。
  • 将来的に異なる処理にしたとしても、驚きは少ない実装方法は何か。

など。

また、共通化の方法として、特に本書で紹介されていたテンプレートメソッドパターンなどの実装は、is a関係を保ちにくいと考えるため個人的には委譲最優先で実装している。