「Kent Beckの実装パターン」を読んだ

実装パターン

実装パターン

メモです。リーダブルコードをより具象化、パターン化した本という印象。

TL;DL

  • 「他人が読んでわかるコード」が「よいコード」
  • 読み手を意識しながらコーディングすることの重要性。いかに意図を正しく伝えるか

プログラマの仕事は,他のプログラマとの間でコミュニケーションを取ることである.マシンとではない.

Implementation

実装パターン

  • 「相手にこのコードで何を伝えたいか」を自問する思考方法
  • 誇りの持てないものに対して無駄にする時間はない、よいコードを書くこと自体が喜びであり、そのコードを他の人が理解し、評価し、使用し、拡張してくれれば、さらに喜びは増す

「責任」についての本

  • 自分とその相棒であるマシンのためだけではなく、他の人のためにコードを作成する

コードを通して考えを伝える

  1. 自分で何を考えているを意識出来るくらいに思考速度を落とす == 直感でコードを書く振りを止める
  2. 他人の重要性を認識する

卓越したプログラムに必要とされる要素 - 動機

  1. コミュニケーション
    • 他の人はこれを見てどう感じるだろう
  2. シンプル
    • 余分な複雑性を取り除き、本質を目立たせる
  3. 柔軟性
    • 複雑を引き起こさない、シンプルから生まれる柔軟性

原則 - 行動

  1. 結果の局所化
    • 変数のコストを低く
  2. 繰り返しの最小化
    • 小さな部品を作る
  3. ロジックとデータの一体化
    • ロジックが操作するデータは近くに
  4. 対称性
  5. 宣言型の表現
    • 型に意図を詰める
  6. 変更頻度
    • 同じタイミングで変更されるデータは近くに

Class

  • classの名前が決まれば操作の名前は後から決まってくる
    • 短く力強く、意味が豊富で的確な
  • Interfaceとクラス階層は相互排他ではない
  • 新しいSubInterfaceを導入することでInterfaceの拡張を安全に行う
  • 状態を持たないVOで暗黙的なシーケンスを無視する
  • static関数を格納したライブラリクラスはいつでもオブジェクトクラスに変換できるように
  • classは関連する状態を一つに纏めるもの

State

  • オブジェクトは、外部の世界に示される振る舞いと、その振る舞いを支えるために使用される状態のパッケージ
  • 似たような状態(近くにあるか、同じ計算で使われている、発生・消滅のタイミングが同時か)は1つに纏め、異なる状態は離しておく
  • flagに基づいて決定を行うコードが重複しているならstrategyパターンを検討する
  • static fieldと引数の両方を使用できるなら引数でクラス間の結合を行う
  • 変数の生存期間、スコープ、型は、コンテキストで伝えることが出来る
  • 変数やメソッドを出来るだけ汎用的な型で宣言する
    • 後から具象クラスを自由に変更できる

Behavior

  • 実装を選択するためのメッセージを広範囲に使用すると、明示的な条件分岐のないコードになる(実行時の型に基づいて)
  • 自分の意図をより明確に伝えるために説明メッセージを用いる

Method

  • 出来るだけ汎用的な型で戻り値を宣言する
  • 複雑なオブジェクト生成をコンストラクタではなく、ファクトリー(static method)に任す
    • コンストラクタは具象クラスに貼り付けるので、ファクトメソッドでコードの抽象度が上げる
      • 抽象的な型を返すことが出来る
      • 意図にあった名前を付けることが出来る
      • ファクトリーの中で何をやっているのか気になるので、オーソドックスな生成だけならコンストラクタを用いる
  • メソッド名では意図を伝達し、実装戦略が重要でないなら含めないべき(呼び出し側がどう見えるかによって命名する)
  • 公開するものを少なくすることにより得られる柔軟性を重視する
  • privateなヘルパーメソッドでサブルールンを隠蔽する + 共通部分を除去する
  • 変換処理は変換後のオブジェクトに変換用のコンストラクタを定義する

Collection

  • Collectionを継承するより委譲を活用するのが良い
    • 意味のある操作だけ公開し、わかりやすい名前を付ける事が出来る
    • 継承だと、不適切な(意図しない)メソッドまで保持することになる(ex. clear)
class Library {
    Collection<Book> books = new ArrayList<>();
    // ...
}

Extended to Framework

  • clientのコードを壊すことなくFWの改善が行えるようにするためには複雑性が増すことの方がコスト的に有利な事がある
  • clietnにはシンプルなインターフェースを提供する
  • 目標のFWは、進化可能なくらい複雑だが、使用するのには十分シンプルであり。進化可能なくらいに応用範囲は狭いが、使用するのに十分適応範囲が広い
  • 公開される詳細の数を減らし、変更される確率の低い詳細を公開する

see also