Help us understand the problem. What is going on with this article?

Mediatorパターン

More than 3 years have passed since last update.

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

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.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした