オブジェクトの振る舞いに関するデザインパターン。
Mediator...「仲介者、まとめ役」の意味
Mediatorパターンの概要
オブジェクト同士がお互いに参照し合わないようにし、
オブジェクトの結合度を弱めるようにする手法をとるパターン
メリット
- オブジェクト同士の結合度を弱める
UML
登場する構成クラス
- Mediator
- 仲介者クラスの抽象クラス
- ConcreteMediator
- 仲介者クラスの具象クラス
このクラスがColleagueクラスのオブジェクトを管理する
- 仲介者クラスの具象クラス
- Colleague
- Mediatorクラスに通知を送るためのメソッドを定義している。だけ。 Colleagueは「同僚」という意味。同僚という言葉は特に意識しなくてよい。同僚というより同列の機能とかの方がしっくりくるかも。
- ConcreateColeageA, ConcreateColeageB, ConcreateColeageC...
- Colleagueクラスの具象クラス
- インスタンス生成するときに、ConcreteMediatorを生成する
- 自分の状態が変わったときにConcreteMediatorに状態を通知する
- ConcreteMediatorに他のオブジェクトの状態を聞く
これってどういう時に使われる?の例
例1
入力フォームを作成するときに、チェックボックスとテキストボックスが存在するとします。
テキストボックスは、チェックボックスにチェックがついている状態じゃないと表示させたくない場合。
登場する構成クラスに当てはめると
テキストボックス (ConcreteColleagueA)、
チェックボックス (ConcreteColleagueB)。
お互いのオブジェクトを参照し合うのではなく、
共通のクラス(Mediator)を介して、お互いのオブジェクトの情報を知る。
例2
RPGの表示例
コード例
[rubyによるMediatorパターンの実装] (http://capm-network.com/?tag=%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Mediator)
#!/usr/bin/env ruby
# 仲介者インタフェース
# メソッドを定義するだけ
class Mediator
def create_colleagues
end
def consultation
end
end
# 具体的な仲介者
class ConcreteMediator < Mediator
def initialize
# Hashでオブジェクト情報を管理する
@colleague = Hash.new
end
# 同僚を登録する
def create_colleagues(colleague)
@colleague.store(colleague.get_name,colleague)
end
# 仲介する
# @param colleague colleagueオブジェクト
# @param to 他のcolleagueオブジェクト名
# @param msg メッセージ
def consultation(colleague, to, msg)
puts("[mediator] from #{colleague.get_name} to #{to}")
@colleague[to].read_msg(msg)
end
end
# 同僚インタフェース
class Colleague
def initialize(name)
@name = name
end
def get_name
return(@name)
end
def set_mediator(mediator)
@mediator = mediator
end
end
# 具体的な同僚1
class ConcreteColleague1 < Colleague
def initialize(name)
super(name)
end
def twitter(to, msg)
@mediator.consultation(self, to, msg)
end
def read_msg(msg)
puts("#{@name} received: #{msg}")
end
end
# 具体的な同僚2
class ConcreteColleague2 < Colleague
def initialize(name)
super(name)
end
def twitter(to, msg)
@mediator.consultation(self, to, msg)
end
def read_msg(msg)
puts("#{@name} received: #{msg}")
end
end
# Client
mediator = ConcreteMediator.new
user1 = ConcreteColleague1.new("user1")
user2 = ConcreteColleague1.new("user2")
# mediatorに登録する
user1.set_mediator(mediator)
user2.set_mediator(mediator)
mediator.create_colleagues(user1)
mediator.create_colleagues(user2)
# 同僚に連絡する
user1.twitter("user2", "I am user1.")
user2.twitter("user1", "I am user2.")
実行結果
[mediator] from user1 to user2
user2 received: I am user1.
[mediator] from user2 to user1
user1 received: I am user2.