GoF本 Mediator
ねらい
モチベーション
- システムをオブジェクトに細分すると再利用性が高まる
- が、オブジェクトの相互作用が増加してくると、このメリットが再び失われる
- 極論、すべてのオブジェクトが自分以外を知っているという状況
- 【補】
nC2 = n(n-1)/2 = O(n^2)
のオーダー
- 【補】
- オブジェクトが単体で成り立たなくなる
- 依存ありきになると、結局一枚岩と変わらない
- 極論、すべてのオブジェクトが自分以外を知っているという状況
- ふるまいのカスタマイズも難しくなる
- ふるまいが多数のオブジェクトで定義される
- 継承してoverrideすべきクラスも多岐にわたってしまう
mediator
オブジェクトをもうけ、総体的なふるまいをカプセル化することでこれらを回避できる- 各々のオブジェクトは
mediator
を通して相互作用する- 【補】相互作用の本数は
O(n)
に減る
- 【補】相互作用の本数は
- 各々のオブジェクトは
つかいどころ
- オブジェクト同士が、よく定義された形で、しかし複雑に相互作用する
- 【補】「よく定義された」というのは、「静的に決まっている」ということか
- オブジェクトが多くのオブジェクトと相互作用するため、再利用が困難
- システムのふるまいをカスタマイズする際に、たくさんのクラスを継承・overrideするのを避けたい
構造
stub
登場人物
Mediator
colleague
オブジェクトと相互作用するインターフェースの定義
ConcreteMediator
Mediator
の実装クラスcolleague
を保持・管理する- システムのふるまいをカスタマイズする際には、これだけ継承・overrideすればよい
Colleague
- システムを構成するクラスのインタフェース
ConcreteColleague classes
- システムを構成するオブジェクトのクラス
- 帰属する
mediator
オブジェクトを知っている - 他の
colleague
と直接は相互作用せず、mediator
を通して間接的に相互作用する
クライアントコードからの利用
colleague
オブジェクトはmediator
にリクエストを送ったり、から受け取ったりするmediator
オブジェクトは、リクエストの交通整理を行い、適切なcolleague
オブジェクトにリクエストを送り、協調動作させる
結果
- システムのふるまいをカスタマイズする際、クラスの継承の数を少なくすることができる
Mediator
だけ派生すればいい
colleague
オブジェクト間を疎結合にできる- オブジェクト間の関連がシンプルになる
- 元々: 多対多
- Mediator Pattern: 1対多 (Mediator vs Colleagues)
- 【補】相互作用の本数も
O(n^2)
からO(n)
になる
- オブジェクトの協調動作に集中できるようになる
Mediator
の実装の中では、colleague
オブジェクト個々のふるまいは抽象化される(実装を見なくて済む)
- 制御が中央集権的になる
- 【補】
Mediator
の複雑性はO(n)
で増加する - 個々の
Colleague
よりは複雑 Mediator
自体が一枚岩になってしまいかねない
- 【補】
実装にあたり考えるべきこと
Mediator
抽象クラスを省くcolleague
オブジェクトたちが協調動作するmediator
オブジェクトが一種類だけなら不要- 疎結合ではなくなる
Colleague
-Mediator
間の相互作用Mediator
をObserverとしてObserverパターンを適用するColleague
クラス群はSubjectに相当colleague
オブジェクトは状態が変化したら通知し、mediator
はこれを購読するmediator
は他のcolleague
にこれを伝播する
Mediator
に、専用の通知インタフェースを定義する
関連するパターン
- Facade Patternとの対比
Facade | Mediator |
|
---|---|---|
類似点 | facadeオブジェクト | mediator オブジェクト |
メッセージのやりとり | Facade -> subsystem classes 単方向 |
Mediator <-> Colleague classes 双方向 |
ねらい | システムを簡単に使うための窓口の提供。 facadeはなくてもシステムは動く |
オブジェクトを協調動作させる。mediator は必要不可欠 |