ケントベック実装パターンまとめ

「実装パターン」についてまとめる。
おおざっぱな内容と、気になった点のみ。
詳細を知りたい方は本を買いましょう。

概要

価値 > 原則 > 後述のパターン

  • 3つの価値がある
  • その価値をかなえるための原則
  • その原則を実現するためのパターン

価値

コミュニケーション
  • 読みやすいということ
シンプル
柔軟性

原則

結果の局所化
  • 変更の結果が一カ所にとどまるようにコードを構成すること
繰り返しの最小化
  • コードコピペするなということ
ロジックとデータの一体化
対称性
宣言型の表現
  • 意図についてはなるべく宣言的に書くようにしよう
変更頻度

同じタイミングで変更されるロジックやデータは同じ場所に置き、変更されるタイミングが異なるロジックやデータは分けておく

  • ここで言っている「変更」というのは、以下の両方を指している
    • ソースの変更
    • データ

各パターン

クラス
  • クラス
    • シンプルなスーパークラス
    • 修飾的なサブクラス名
    • 抽象インターフェース
    • インターフェース
      • 「XXXImpl.javaという名前がひどい」という意見に同意w
    • 抽象クラス
    • 別バージョンのインターフェース
      • インターフェースAに操作を追加したくなったらどうする?
      • Aを継承したインターフェースBを作成しよう
    • バリューオブジェクト
  • 特化
    • サブクラス
    • 実装クラス
    • 内部クラス
  • インスタンス固有の振る舞い
    • 条件分岐
    • 委譲
    • プラガブルセレクタ
    • 匿名内部クラス
  • ライブラリクラス
状態
  • 状態
  • アクセス
  • 直接アクセス
  • 間接アクセス
  • 共通の状態
  • 可変の状態
  • 外部の状態
  • 変数
  • ローカル変数
      • ローカル変数には大きく言って以下の種類がある
        • コレクター
        • カウント
        • 説明
        • 再利用
        • 要素
フィールド
  • 引数
    • コレクティングパラメータ
      • 個人的には「メソッドの中で引数のオブジェクトの中身を変更」するのは分かりづらくなるので嫌いだが、本書にあった以下の例ではしょうがないかな。
public class Node {
  public List asList() {
    List results = new ArrayList();
    addTo(results); //この辺がコレクティングパラメータ
    return results;
  }
  private void addTo(List elements) {
    elements.add(getValue());
    for(Node each : getChildren() )
      each.addTo(elements);
  }
}
    • パラメータオブジェクト
setOuterBounds(x, y, width, height);
setInnerBounds(x, y, width, height);
//↓以下のように記述しよう
setOuterBounds(bounds);
setInnerBounds(bounds.expand(-2));
  • 定数
  • 役割を示す名前
      • 以下の文に激しく同意

変数の命名体系の多くが、名前の中に方の情報を含めているが、私の命名体系は違う。コンパイラに何度も変数の型を伝えているのに、なぜ同じ情報を変数名にも組み込まなければならないのだろうか。Cのような、型のエラーを防止するための手段があまりない言語では、型の情報を変数名に入れることは理解できる。しかしJavaには、型のエラーを回避するための仕組みが十分に用意されている。

  • 宣言される型
  • 初期化
    • 早期初期化
    • 遅延初期化
振る舞い
  • 制御フロー
  • メインフロー
  • メッセージ