mediatorは日本語で「仲裁人」,「調停者」という意味になる.Mediatorパターンは,オブジェクト群の相互作用をカプセル化するオブジェクトを定義することで,オブジェクトが直接互いに参照しないようにし,独立して再利用できるようにするパターンである.
Mediatorパターンの主な要素は以下である.
javaimport java.util.ArrayList;
import java.util.List;
// Mediator
interface Mediator {
void register(Colleague colleague);
void relay(Colleague colleague);
}
// Concrete Mediator
class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
@Override
public void register(Colleague colleague) {
if (!colleagues.contains(colleague)) {
colleagues.add(colleague);
colleague.setMediator(this);
}
}
@Override
public void relay(Colleague colleague) {
for (Colleague ob : colleagues) {
if (!ob.equals(colleague)) {
((Colleague) ob).receive();
}
}
}
}
// Colleague
abstract class Colleague {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
// Concrete Colleague
class ConcreteColleagueA extends Colleague {
@Override
public void receive() {
System.out.println("ConcreteColleagueA receive");
}
@Override
public void send() {
System.out.println("ConcreteColleagueA send");
mediator.relay(this);
}
}
class ConcreteColleagueB extends Colleague {
@Override
public void receive() {
System.out.println("ConcreteColleagueB receive");
}
@Override
public void send() {
System.out.println("ConcreteColleagueB send");
mediator.relay(this);
}
}
// Client
public class MediatorPattern {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague colleagueA = new ConcreteColleagueA();
Colleague colleagueB = new ConcreteColleagueB();
mediator.register(colleagueA);
mediator.register(colleagueB);
colleagueA.send();
colleagueB.send();
}
}
P2Pのような構造(いや,Mediatorを介すからP2Pではない)ROS1みたいな構造(Mediatorがroscore)を実装したいときに便利.ROSを知らない人には伝わらなくてすみませんが,個人的にROS1が一番しっくり来てしまいました…
クライアントとColleagueオブジェクトを実装する際は,他の要素をあまり意識する必要が無い.
しかし,Mediatorの実装が複雑になりがちだなと感じた.実装例は非常に単純なものだったので,まだ理解できたが,もっと複雑なプログラムになってくるとMediatorの読解・実装が困難になり,バグを生みやすくなりそう.
Mediatorに対してまた別のデザインパターンを適用して改善できたらいいかもしれない(いや,もっと複雑になってしまうかも?).