DDD / Intention-Revealing Interfaces


意図の明白なインタフェース-INTENTION-REVEALING INTERFACES (p.246)

要約

意図の明白なインタフェース-INTENTION-REVEALING INTERFACES
  • モデルと明確に結びついていないコードは、実行した際に何が起きるか理解しづらく、また変更の影響を予測することも難しい。
  • 前章で明示的にモデル化した「ルール」や「計算」を実装する際には細かなルールや計算方法を知らなければならないが、オブジェクトを使ってカプセル化することで、クライアントコードはシンプルになり、高次の概念的用語を使って記述できるようになる。
***

問題

  • あるオブジェクトを効率よく使うために知るべきことをインタフェースが何も示さない場合、クライアントの開発者は、詳細を理解するために内部を探索することになるだろう。クライアントのコードを読む人も同じことをしなければならなくなる。こうして、カプセル化の利点は失われてしまう。
  • 我々は、常に認知負荷の増大と戦っている。クライアントの開発者が、コンポーネントがどうやって動いているかの詳細で頭が一杯になってしまっていたら、自分の仕事の詳細まで頭が回らなくなってしまう。これは、コンポーネント設計とクライアント設計を同じ人が担当していても発生する。これは、人間が一度に考えられる要素の数には限界があるからだ。

問題サマリ

  • 開発者があるコンポーネントを使う際に、その実装まで考慮しなければならないなら、カプセル化の価値は失われている。
  • 作成者以外の開発者が、あるオブジェクトの操作の目的を知る際に実装にもとづいた推測が必要なら、その開発者は偶然によってしか操作やクラスの果たすべき役割を推測できないかもしれない。
  • 推測した役割が意図したものでない場合、コードはその時はうまく動くかもしれないが、設計の概念的な基盤は損なわれ、開発者たちはお互いに誤解したまま仕事を続けることになるだろう。

解決

  • 概念をクラスやメソッドとして明示的に表すことによる価値を享受するためには、概念を反映する名前をつけなきゃならない。
  • クラス名やメソッド名は、開発者間のコミュニケーション(の質・量)を向上させたり、システムをより抽象化するためのまたとない機会となる。
  • Kent BeckはINTENTION-REVEALING SELECTORパターンで、メソッド名で目的を表すように記述している。
  • 型名、メソッド名、引数名などはすべて合わさって、INTENTION-REVEALING INTERFACEを構成する。

解決方法サマリ Therefore:

  • クラスや操作には、その効果や意図を表す(どうやって実現しているかを参照しなくてもわかる)名前をつけよ。
  • こうすることで、クライアント開発者は内部詳細を知る必要がなくなる。
  • これらの名前は、チームメンバがすぐにその意味を推測できるように、ユビキタス言語に沿っているべきである。
  • クライアント開発者の視点で考えることを忘れないために、クラスや操作を実装する前にテストを書け。
  • トリッキーなメカニズムはすべてカプセル化によって(意味というより)意図を表す抽象化されたインタフェースの背後に隠すべき。
  • ドメインの公開されたインタフェースでは、Whatを記述し、Howを記述してはならない。
表すもの表さないもの
ルールや関連どのようにして強制されるか
イベントやアクションどのように実行されるか
方程式どのように解くか
質問どうやって回答を見つけるか
***

例:Refactoring: A Paint-Mixing Application

  • Paintクラス(before)
    • v
    • r
    • y
    • b
    • paint(Paint)
  • paint(Paint)が何をするメソッドなのかは、コードを読んでみないとわからない。
  • コードを読んでみると、2つのPaintを結合するらしい。
    • Volumeが増える
    • 色が混ざる
  • テストを書いてみると、クライアントの視点からクラスを見ることが出来る。
    • テストコードを見ても何をやっているのかわからない
  • TDD的な感じで改善
  • Paint(after)
    • volume
    • red
    • yellow
    • blue
    • mixin(Paint)
  • 新たな名前(mixin)で全てがわかるわけではないが、だいぶよくなった。
    ***
  • サブドメイン全体は、別個のモジュール群として切り分けられ、INTENTION-REVEALING INTERFACESによってカプセル化されるかもしれない。
    • プロジェクトに焦点をあて、大きなシステムの複雑性を管理する方法については、15章「Distillation」の COHESIVE MECHANISMS や GENERIC SUBDOMAINS でより詳しく議論する。
  • 次の2つのパターンでは、メソッド呼び出しの結果が予測できるようにすることを試みる。
    • 複雑なロジックは、SIDE-EFFECT-FREE FUNCTIONSで安全に実行される。
    • システム状態を変更するようなメソッドは、ASSERTIONSで特性を明らかにされる。

担当者のつぶやき

  • ぐは、書きづらい…少しだけアレンジしました。

みんなの突っ込み


まとめ (議事録)