まず、メッセージについて検討します。
メッセージ転送の部分のソースコードは次の4種類に分類できます。
メッセージ転送の種類は、次の4種類に分類できます。
a, b のタイプのメッセージは、その2つのオブジェクトが、どの
(スーパー)クラスのオブジェクトであるかという、組み合わせの
限定が必ず生まれます。
何故なら、その2つのオブジェクトが、対象となるメッセージを送
る(または受け取る)ことができなければならないからです。
それを保証するために、継承(Java の「インターフェイス継承」
)させて、実装(オーバーライド)します。(*1)
インターフェイス継承は、トリガされる側 B, D に限り用いられま
す。
c のタイプのメッセージは、オブジェクトのコンポーネント化を進
めます。
なぜなら、仲介役のオブジェクト E が主導権を持っていて、コン
ポーネント B, D にトリガしていきますが、コンポーネント B が
受け取ることができないメッセージを別のオブジェクトに送ったり、
コンポーネント D が持っていないメッセージ(情報)を別のオブ
ジェクトから受け取ったりすることができるからです。
コンポーネントは、なるべく、あらかじめ用意してあるメソッド以
外のインターフェイスをなるべく用意しなくて済むように、つまり
インターフェイス継承をしなくて済むように設計します。そうでな
ければ、使いにくいコンポーネントになってしまいます。
話は変わりますが、コンポーネント化を進めるためには、もう1つ
カギがあります。それは、コンポーネントから生じたイベント(た
とえば、ボタンオブジェクトのボタンが押されたイベントなど)を、
コンポーネント自身が処理するのではなく、仲介役のオブジェクト
に通知して処理させることです。[*1]
その理由は、イベントによって処理する対象のオブジェクトとボタ
ンオブジェクトとの間でメッセージ転送が行われるため、そのオブ
ジェクトと関連しなければならなくなるからです。つまり、ボタン
の使われる場面によってそれぞれ別の関連をしていなければならな
くなります。
仲介役のオブジェクトに通知するには(Delphi の)メソッドポイ
ンタ[*2]を用いれば、スマートに実装できます。(*2)
仲介役のオブジェクト E を「役割場, Role Field」[*3]と認識す
れば、更に再利用性が高まります。
たとえば、アプリケーション、スレッド、ネットワークサーバ、エ
ージェント、ウィンドウ、ストリーム、コンテナ、描画ツールなど
が役割場です。
それぞれの役割場には一連の処理に関する役割があります。たとえ
ば、ストリームはファイルなどの通路という役割、コンテナはオブ
ジェクトの集まりを管理するという役割、ネットワークサーバは高
速に処理をするという役割があります。
仲介役のオブジェクト E は、コンポーネントのためにメッセージ
をコントロールしますが、役割場と認識して役割インターフェイス
[*4]と関連するようにすることで、オブジェクトの再利用性をも高
めることができます。(*3)
役割場は、分割統治法とうまくマッチします。それぞれの役割をサ
ブ役割場に分担することで、構造的な処理構成をとることができま
す。
サブ役割場に処理を依頼するようにメッセージを送ることを「委譲」
と呼びます。(*4)
サブ役割場をコンポーネントにすることは、よくあります。現に、
ストリームや描画ツールなどはコンポーネントになっています。
役割場は、プログラム上、集約と同じ構造をしていますが、オブジ
ェクトと異なりモデルの対象となるものが存在しません。ですから、
役割場が関連しているオブジェクトは、完全に所有しているわけで
はなく別の役割場と関連することがあります。
たとえば、ファイルオブジェクト( C 言語の FILE* など)をスト
リームという役割場と関連(リンク)させてアクセスしますが、フ
ァイルオブジェクトは、アプリケーションという役割場によって管
理(関連)されています。(*5)
役割場のメソッドは、プログラムがしやすいのではと考えています。
たとえば、Visual Basic や Delphi などは、メインウィンドウ(
フォーム)が仲介役になっていて、イベントハンドラ(イベントプ
ロシージャ)や自分が作ったサブメソッドがたくさんできることに
気付くと思います。それだけ役割場のメソッドにすることが自然な
発想であることがいえるのではないかと思います。その理由はたぶ
ん、第三者の立場に立ってオブジェクトを処理していくからではな
いでしょうか。
しかし、役割場のメソッドに置かれた「処理」は、役割場に依存し
ているため、再利用性は低いでしょう。
そこで、役割場を引数に取らないグローバルな関数、または(その
引数の中の1つの)オブジェクトのメソッドを作って再利用性を高
めます。このメソッドも、はじめに検討したメッセージと同じよう
にスーパークラスの制限を受けますが、メッセージではなく処理で
すから、その実装は新たに作り直す(オーバーライドする)ことは
無いでしょう。
この場合、実装も含んだ多重継承が非常に有効であると考えていま
す。
以上をパターン化したオブジェクト図を示します。
なお、命名の理由は、Component, Role interface, Atom object
and role Field Totalized Pattern. すなわち、CRAFT Pattern
というわけです。
参考資料