伝えよ、尋ねるな

2013年9月5日

伝えよ、尋ねるなは、オブジェクト指向はデータとそれを操作する関数をまとめることであることを人々に思い出させるための原則です。これは、オブジェクトにデータを求めてそれに対して操作するのではなく、オブジェクトに何をすべきかを伝えるべきであることを思い出させてくれます。この原則はオブジェクトに動作を移動してデータと共存することを促します。

例を挙げて説明してみましょう。ある値を監視して、その値がある制限を超えると警告を発する必要があるとしましょう。これを「尋ねる」スタイルで書くと、次のようなデータ構造になるかもしれません…

AskMonitorクラス…

  private int value;
  private int limit;
  private boolean isTooHigh;
  private String name;
  private Alarm alarm;

  public AskMonitor (String name, int limit, Alarm alarm) {
    this.name = name;
    this.limit = limit;
    this.alarm = alarm;
  }

…そして、このデータを取得するためのアクセサを組み合わせます

AskMonitorクラス…

  public int getValue() {return value;}
  public void setValue(int arg) {value = arg;}
  public int getLimit() {return limit;}
  public String getName()  {return name;}
  public Alarm getAlarm() {return alarm;}

データ構造はこのように使います

AskMonitor am = new AskMonitor("Time Vortex Hocus", 2, alarm);
am.setValue(3);
if (am.getValue() > am.getLimit()) 
  am.getAlarm().warn(am.getName() + " too high");

「伝えよ、尋ねるな」は、代わりにモニターオブジェクト自体の中に動作を入れるべきであることを思い出させてくれます(同じフィールドを使用する)。

TellMonitorクラス…

  public void setValue(int arg) {
    value = arg;
    if (value > limit) alarm.warn(name + " too high");
  }

これは次のように使われます

TellMonitor tm = new TellMonitor("Time Vortex Hocus", 2, alarm);
tm.setValue(3);

多くの人は、「伝えよ、尋ねるな」を有用な原則だと考えています。オブジェクト指向設計の基本原則の1つは、データと動作を組み合わせることです。これにより、システムの基本要素(オブジェクト)がその両方を含めることができます。これは多くの場合、データとそのデータを操作する動作が密結合されているため良いことです。一方が変わるともう一方も変わり、一方を理解することでもう一方も理解できます。密結合されているものは同じコンポーネントに収めるべきです。伝えよ、尋ねるなを考えることは、プログラマーが配置の共存をどのように増やせるかを確認する方法になります。

しかし、私は個人的に伝えよ、尋ねるなは使っていません。私はデータと動作の共存を探すので、よく同様の結果につながります。私が伝えよ、尋ねるなについて不可解に感じるのは、それが人々がゲッターエラディケーターになることを奨励するのを目撃したことがあるからです。つまり、すべての照会メソッドを取り除こうとするのです。しかし、オブジェクトが情報を提供することで効果的にコラボレーションする場合があります。好例は、入力を取って、埋め込みドキュメントを使用するなど、クライアントを簡素化するように変換するオブジェクトです。伝えよ、尋ねるなに従うと、適切な照会メソッドがあれば問題が簡略化されるのに、伝えることだけにこだわり、複雑になるコードを見たことがあります[1]。私にとって伝えよ、尋ねるなは、動作とデータを共存させるための足がかりですが、強調する価値のあるポイントだとは思いません。

関連記事

この принципы は、アンディ・ハントと「Prag」のデイブ・トーマス(プラグマティック・プログラマー)に関連付けられることが最も多いです。彼らはIEEE Softwareコラムウェブサイトの投稿で記しています。

メモ

1: そして、さらにデータと動作を共存させるという基本的な原理でさえ、レイヤー化などの他の懸念事項を優先して破棄されるべき場合があります。優れた設計はすべてトレードオフであり、データと動作を共存させることは考慮すべき要素の1つにすぎません。