ravelll の日記

よしなに

オブジェクト指向設計実践ガイド 第4章

パブリックインターフェースについての話。デメテルの法則についても触れていました。

第4章 柔軟なインターフェースを作る

  • オブジェクト指向アプリケーションは「クラスから成り立ち」「メッセージによって定義される」
  • オブジェクトの責任 = オブジェクトが何を知っているか
  • オブジェクトの依存関係 = オブジェクトが誰を知っているか

4.1 インターフェースを理解する

  • オブジェクト同士が複雑に依存してしまうような設計の問題は、クラスが何を「する」かでなく、何を「明らかにする」か、の視点が欠けていることにある
  • 他のオブジェクトからの利用が意図されているメソッドが、そのクラスのパブリックインターフェースを構築する

4.2 インターフェースを定義する

  • レストランの厨房から見て、お客さんが使うことが期待されるパブリックインターフェースはメニュー
    • メニューを使うことで厨房が「どのように」料理を作るかを関知させず「何を」望むかをお客さんに頼ませることができる
  • パブリックインターフェースの特性
    • クラスの主要な責任を明らかにする
    • 外部から実行されることが想定される
    • 気まぐれに変更されない
    • 他者がそこに依存しても安全
    • テストで完全に文書化されている
  • パブリックインターフェースはクラスの責任を明確に述べる契約書
  • 「変更の可能性が低いところにのみ依存する」という考えはクラス内のメソッドにも当てはまる

4.3 パブリックインターフェースを見つける

  • ドメインオブジェクト = アプリケーションにおいてデータと振る舞いの両方を兼ね備える名詞を表すもの
  • 設計時にはドメインオブジェクトに集中はせず、オブジェクト間のメッセージに注意を向ける
  • オブジェクトとメッセージを実験するにはシーケンス図を使うと良い
    • パブリックインターフェースをあらわにし、実験し、定義するための手段となる
    • メッセージに集中することを助け、テストで最初に明らかにしたいことへの合理的な見当をつけられるようになる
  • メッセージに基づく視点はクラスに基づく視点よりも柔軟なアプリケーションを生む
  • オブジェクトが存在するからメッセージを送るのではなく、メッセージを送るためにオブジェクトは存在する
  • パブリックインターフェースが小さい = 他から依存されるメソッドがわずかしか無い

4.4 一番良い面(インターフェース)を表に出すコードを書く

  • インターフェースこそが全てのテストや他のどんなコードよりもアプリケーションを定義し将来を決定づける
  • プライベートメソッドは全くテストしない、もしくはパブリックなメソッドからは隔離する
    • 不安定なプライベートメソッドに依存するテストを書かない
  • 外部フレームワークへの依存は技術的負債の一形態である
  • パブリックインターフェースを構築するときは、他者に要求するコンテキストが最小限になることを目指す
    • メッセージの送り手が、クラスがどのように振る舞いを実装しているかを知ることなく、望むものを得られるようにする

4.5 デメテルの法則

  • デメテルは3つ目のオブジェクトにメッセージを送る際、異なる型の2つ目のオブジェクトを介すことを禁じる
    • 「直接の隣人にのみ話しかける」
  • 中間オブジェクトを介して遠くの属性を取得することが最も低コストな場合もある
    • 変更のコスト・頻度と、違反修正のコストを比べてバランスをとる
    • デメテルの法則を違反することで負うリスクは安定した属性に対しては低い
  • メッセージチェーンを除去する方法の1つは、メッセージを移譲すること
    • 結合を隠しただけで実際にはコードの結合が解かれていないような場合もある。移譲は注意して行うこと
  • メッセージに基づく視点でメッセージを見つけたなら、そのメッセージは何らかのオブジェクトのパブリックインターフェースとなる
    • そのオブジェクトが何のオブジェクトかはメッセージ自体が導いてくれる

4.6 まとめ

  • オブジェクト指向アプリケーションは、オブジェクト間で交わされるメッセージによって定義される
    • メッセージの交換はパブリックインターフェースに沿って行われる
  • メッセージが「受け手がどのように振る舞うか」を伝えるのではなく、相手を「信頼」し送り手が望むことを頼むものであるとき、柔軟なパブリックインターフェースを自然に進化させていく