Mediatorパターンについてまとめてみた

nishigo

みなさんこんにちわ、最近は春の訪れがやってきてるとは思えないほど寒空でしたが、
道ばたにタンポポも咲き始め、花見が楽しみなシーズンになってきましたね。
「さまざまのこと思ひ出す桜かな」
なんて芭蕉の歌を書いてみると、一人で桜を見て思い耽るのも悪くないかなと感じてしまうnishigoです。

さて、今回はGoFの23のパターンの中のMediatorパターンに焦点を合わせます。
オブジェクト指向でモデリングをすると、必然的に多数のオブジェクトに分割され、それらの間が(メソッドを経由した)メッセージでつながることになります。

オブジェクト数が増えると、メッセージの通知先が増えることになりがちです。その結果、オブジェクトどうしが複雑に絡み合う状態となってしまい、メッセージがどの順にどこへ流れるのかが分かりずらくなってしまいます。

この問題を解決する手段として、Mediatorというパターンが役に立ちます。
Mediator(仲介者)という名の通り、各オブジェクトの仲介をするオブジェクトを間に置いて、オブジェクト間のつながりを整理します。

単純な例として、Person(個人)とGroup(グループ)というクラスを考えます。PersonとGroupは多対多の関係が成立するものとします。
つまり、Groupに複数のPersonが所属すること(これは普通)も、Personが複数のGroupに所属することもあるものとします。

所属関係が成立するPersonとGroupの関連付けの方法として、リンク(参照)を張るという方法は

1

単純で分かりやすい方法です。しかし、リンクの数が増えやすい(PersonとGroupのオブジェクト数の積の半分)という問題があります。

オブジェクト図

そこで、両者の間にMappingというMediatorクラスを置くことで、このリンク数を減らします。Person, Groupの各オブジェクトはMappingのオブジェクト(以下、Mediator)だけとリンクを張ります。

3

ちょうど、車輪のハブのようにMediatorを中心にして、各オブジェクトはMediatorを経由して、他のオブジェクトとつながります。

各PersonはMediatorに接続するときに、自分が所属するGroupの一覧をMediatorに通知して、その対応関係はMediatorが保持します。
こうすることにより、GroupオブジェクトがMedeiatorに自分に所属しているPersonオブジェクトの一覧を取得するときは、Mediatorは保持している対応関係表からPersonのオブジェクトをGroupに返します。

4

この構成を取った場合、オブジェクトはMediatorと1:1に対応するため、オブジェクト数が増えたとしても、リンクの数が加速度的に増加することはありません。

この構成のMediatorが、各オブジェクトの通知手段の機能を持つようになると、同じくGoFのObserverパターンとなります。

Observerパターンの場合、それぞれのオブジェクトは自分がリンクを張っているObserver(通知手段を持ったMediatorオブジェクト、以下同じ)へ通知(イベント)を送信します。
それを受け取ったObserverは他のオブジェクトへその通知(イベント)を転送することで、メッセージを通知します。

Obserberパターン

典型的な例としてはウィンドウシステムにおける、ウィンドウとウィンドウマネージャの関係があります。
ウィンドウは自分のウィンドウの描写内容のアップデートが必要なったときに、Observerであるウィンドウマネージャに、画面描写のアップデートの要求を通知することで、他のウィンドウの状態を確認しに行き、最終的な画面を描写します。

[シーケンス図]Mediator

本来のObserverパターンの目的は、1つのオブジェクトの状態を複数のオブジェクトに通知することです。そのための通知の構造としてMediatorが使われることがあります。

このようにMediator, Observerは非常に応用範囲の広いパターンです。ぜひ、マスターしましょう。

日本にハブ空港が無いと言われる昨今ですが、オブジェクトの世界でもハブとなるものは重要なんですね。
社内でも仲介者にまず通知して、うまく連携を取っていけるよう努めていきたいと思います :-)

nishigo

Posted by nishigo