LoginSignup
20
6

More than 5 years have passed since last update.

Mediatorパターン

Last updated at Posted at 2016-12-13

オブジェクトの振る舞いに関するデザインパターン。

Mediator...「仲介者、まとめ役」の意味

Mediatorパターンの概要

オブジェクト同士がお互いに参照し合わないようにし、
オブジェクトの結合度を弱めるようにする手法をとるパターン

メリット

  • オブジェクト同士の結合度を弱める

UML

Qiita

登場する構成クラス

  • Mediator
    • 仲介者クラスの抽象クラス
  • ConcreteMediator
    • 仲介者クラスの具象クラス
      このクラスがColleagueクラスのオブジェクトを管理する
  • Colleague
    • Mediatorクラスに通知を送るためのメソッドを定義している。だけ。 Colleagueは「同僚」という意味。同僚という言葉は特に意識しなくてよい。同僚というより同列の機能とかの方がしっくりくるかも。
  • ConcreateColeageA, ConcreateColeageB, ConcreateColeageC...
    • Colleagueクラスの具象クラス
    • インスタンス生成するときに、ConcreteMediatorを生成する
    • 自分の状態が変わったときにConcreteMediatorに状態を通知する
    • ConcreteMediatorに他のオブジェクトの状態を聞く

これってどういう時に使われる?の例

例1
入力フォームを作成するときに、チェックボックスとテキストボックスが存在するとします。
テキストボックスは、チェックボックスにチェックがついている状態じゃないと表示させたくない場合。

登場する構成クラスに当てはめると
テキストボックス (ConcreteColleagueA)、
チェックボックス (ConcreteColleagueB)。
お互いのオブジェクトを参照し合うのではなく、
共通のクラス(Mediator)を介して、お互いのオブジェクトの情報を知る。

例2
RPGの表示例

コード例

rubyによる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.
20
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
6