Mediator パターン (オブジェクト同士が互いに参照し合うことがないように, 仲介役となるオブジェクトを介して制御を行う方法を提供する)

[Mediator] という英単語は, [仲介者] を意味する.

このパターンは, 複雑に絡み合った複数のオブジェクト間の関係を, 必ず [仲介者] を介して処理を行うようにすることで, 単純かつ明快なインタフェースを提供するパターン.

つまり, [Mediator] パターンとは, 管轄下にある複数のオブジェクト各々からの問い合わせを受け, 適宜判断を行い, 管轄下にあるオブジェクト全体, または一部へ指示を出す [仲介人] の役割を果たすクラスを利用するパターン.

役割

  1. Mediator (仲介者):
[Colleague] からの相談を一手に引き受け, またそれを元に判断を下ろし, [Colleague] へ指示を出す. 各 [Colleague] からの相談受付の窓口インタフェースを定義する. [consultation] 管轄下に置く [Colleague] を格納するためのインタフェースを定義する. (addColleague)
  1. ConcreteMediator (具体的な仲介者):
[Mediator] のインタフェースを実装する. 実際に [Colleague] を保持し, それらから相談を受け, 判断を下ろし, それらに指示を出す.
  1. Colleague (同僚):
他の [Colleague] を制御したい場合は, [Mediator] に相談する. [Mediator] からの指示を受ける窓口インタフェースを定義する. (advice) 自身が相談する [Mediator] を格納するためのメソッドを定義する. (setMediator).
  1. ConcreteColleague[A|B] (具体的な同僚):
[Colleague] のインタフェースを実装する.
  1. Client (利用者):
[Mediator] パターンを適用したクラスを用い処理を行う.

クラス図

Mediator パターンのクラス図

_images/designpattern-mediator012.gif

ソースコード

  1. Mediator.java
1
2
3
4
public abstract class Mediator{
    public abstract void addColleague(Colleague colleague);
    public abstract void consultation(Colleague colleague);
}
  1. ConcreteMediator.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class ConcreteMediator extends Mediator{
    Map<String, Colleague>colleagues = new HashMap<String, Colleague>();

    public void addColleague(Colleague colleague){
	colleagues.put(colleague.getName(), colleague);
    }

    public void consultation(Colleague colleague){
	String name = colleague.getName();
	System.out.println(name + " からの相談.");

	Iterator<String> it = colleagues.keySet().iterator();
	
	while(it.hasNext()){
	    Colleague colleagueTmp = (Colleague)colleagues.get(it.next());
	    if(!(colleagueTmp.getName().equals(colleague.getName()))){
		colleagueTmp.advice(name + " からの相談があった.");
	    }
	}
	
    }

}
  1. Colleague.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public abstract class Colleague{
    protected Mediator mediator;
    private String name;

    public Colleague(String name){
	this.name = name;
    }

    public String getName(){
	return name;
    }

    public void setMediator(Mediator mediator){
	this.mediator = mediator;
    }

    public abstract void advice(String msg);
    public abstract void run();
}

4-1. ConcreteColleagueA.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class ConcreteColleagueA extends Colleague{
    public ConcreteColleagueA(String name){
	super(name);
    }

    public void run(){
	mediator.consultation(this);
    }

    public void advice(String msg){
	System.out.println("ConcreteColleagueA: " + msg);
    }
}

4-2. ConcreteColleagueB.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class ConcreteColleagueB extends Colleague{
    public ConcreteColleagueB(String name){
	super(name);
    }

    public void run(){
	mediator.consultation(this);
    }

    public void advice(String msg){
	System.out.println("ConcreteColleagueB: " + msg);
    }
}
  1. Client.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class Client{
    public static void main(String[] args){
	Mediator mediator = new ConcreteMediator();
	Colleague colA = new ConcreteColleagueA("A");
	Colleague colB = new ConcreteColleagueB("B");

	mediator.addColleague(colA);
	mediator.addColleague(colB);

	colA.setMediator(mediator);
	colB.setMediator(mediator);

	colA.run();
	colB.run();
    }
}

上記のプログラムの実行結果:

[wtopia Mediator]$ java Client
A からの相談.
ConcreteColleagueB: A からの相談があった.
B からの相談.
ConcreteColleagueA: B からの相談があった.