Mediatorパターンは、複数のオブジェクト間の複雑なコミュニケーションを管理し、直接的な依存関係を避けることで、オブジェクト同士の結合度を低減させるデザインパターンです。
このパターンを使うことで、システム全体のメンテナンス性や拡張性が向上します。
この記事では、Mediatorパターンの基本概念、実際の使い方、そしてJava、C++、C#、VB.NETでの実装サンプルを提供します。
Mediatorパターンとは
Mediatorパターンは、オブジェクト間の通信を一つのMediator(仲介者)オブジェクトに集中させることで、個々のオブジェクト同士の依存関係を排除し、シンプルな構造を保つデザインパターンです。
これにより、システムの変更が容易になり、柔軟性が向上します。
Mediatorパターンの使い方
Mediatorパターンは、主にオブジェクト間の依存関係を減らしたいときや、複数のオブジェクトが同時にやり取りをする状況で役立ちます。
たとえば、チャットルームのようなシステムでは、各参加者(オブジェクト)がMediatorを介してメッセージを送受信するため、参加者同士が直接やり取りをする必要がなくなります。
Mediatorパターン実装サンプル
以下に、Mediatorパターンの実装サンプルをそれぞれJava、C++、C#、VB.NETで示します。
JavaによるMediatorパターンの実装
public interface Mediator {
void sendMessage(String message, Colleague colleague);
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receiveMessage(String message);
}
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
public void sendMessage(String message) {
System.out.println("Colleague1 sending message: " + message);
mediator.sendMessage(message, this);
}
public void receiveMessage(String message) {
System.out.println("Colleague1 received message: " + message);
}
}
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
public void sendMessage(String message) {
System.out.println("Colleague2 sending message: " + message);
mediator.sendMessage(message, this);
}
public void receiveMessage(String message) {
System.out.println("Colleague2 received message: " + message);
}
}
public class ConcreteMediator implements Mediator {
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public void setColleague1(ConcreteColleague1 colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(ConcreteColleague2 colleague2) {
this.colleague2 = colleague2;
}
public void sendMessage(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.receiveMessage(message);
} else {
colleague1.receiveMessage(message);
}
}
}
public class MediatorPatternDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.sendMessage("Hello from Colleague1");
colleague2.sendMessage("Hello from Colleague2");
}
}
C++によるMediatorパターンの実装
#include
#include
class Colleague;
class Mediator {
public:
virtual void sendMessage(const std::string& message, Colleague* colleague) = 0;
};
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* mediator) : mediator(mediator) {}
virtual void receiveMessage(const std::string& message) = 0;
};
class ConcreteColleague1 : public Colleague {
public:
ConcreteColleague1(Mediator* mediator) : Colleague(mediator) {}
void sendMessage(const std::string& message) {
std::cout << "Colleague1 sending message: " << message << std::endl;
mediator->sendMessage(message, this);
}
void receiveMessage(const std::string& message) {
std::cout << "Colleague1 received message: " << message << std::endl;
}
};
class ConcreteColleague2 : public Colleague {
public:
ConcreteColleague2(Mediator* mediator) : Colleague(mediator) {}
void sendMessage(const std::string& message) {
std::cout << "Colleague2 sending message: " << message << std::endl;
mediator->sendMessage(message, this);
}
void receiveMessage(const std::string& message) {
std::cout << "Colleague2 received message: " << message << std::endl;
}
};
class ConcreteMediator : public Mediator {
private:
ConcreteColleague1* colleague1;
ConcreteColleague2* colleague2;
public:
void setColleague1(ConcreteColleague1* colleague) {
colleague1 = colleague;
}
void setColleague2(ConcreteColleague2* colleague) {
colleague2 = colleague;
}
void sendMessage(const std::string& message, Colleague* colleague) {
if (colleague == colleague1) {
colleague2->receiveMessage(message);
} else {
colleague1->receiveMessage(message);
}
}
};
int main() {
ConcreteMediator mediator;
ConcreteColleague1 colleague1(&mediator);
ConcreteColleague2 colleague2(&mediator);
mediator.setColleague1(&colleague1);
mediator.setColleague2(&colleague2);
colleague1.sendMessage("Hello from Colleague1");
colleague2.sendMessage("Hello from Colleague2");
return 0;
}
C#によるMediatorパターンの実装
using System;
public interface Mediator {
void SendMessage(string message, Colleague colleague);
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void ReceiveMessage(string message);
}
public class ConcreteColleague1 : Colleague {
public ConcreteColleague1(Mediator mediator) : base(mediator) {}
public void SendMessage(string message) {
Console.WriteLine("Colleague1 sending message: " + message);
mediator.SendMessage(message, this);
}
public override void ReceiveMessage(string message) {
Console.WriteLine("Colleague1 received message: " + message);
}
}
public class ConcreteColleague2 : Colleague {
public ConcreteColleague2(Mediator mediator) : base(mediator) {}
public void SendMessage(string message) {
Console.WriteLine("Colleague2 sending message: " + message);
mediator.SendMessage(message, this);
}
public override void ReceiveMessage(string message) {
Console.WriteLine("Colleague2 received message: " + message);
}
}
public class ConcreteMediator : Mediator {
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public void SetColleague1(ConcreteColleague1 colleague) {
colleague1 = colleague;
}
public void SetColleague2(ConcreteColleague2 colleague) {
colleague2 = colleague;
}
public void SendMessage(string message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.ReceiveMessage(message);
} else {
colleague1.ReceiveMessage(message);
}
}
}
public class MediatorPatternDemo {
public static void Main(string[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.SetColleague1(colleague1);
mediator.SetColleague2(colleague2);
colleague1.SendMessage("Hello from Colleague1");
colleague2.SendMessage("Hello from Colleague2");
}
}
VB.NETによるMediatorパターンの実装
Public Interface Mediator
Sub SendMessage(ByVal message As String, ByVal colleague As Colleague)
End Interface
Public MustInherit Class Colleague
Protected mediator As Mediator
Public Sub New(ByVal mediator As Mediator)
Me.mediator = mediator
End Sub
Public MustOverride Sub ReceiveMessage(ByVal message As String)
End Class
Public Class ConcreteColleague1
Inherits Colleague
Public Sub New(ByVal mediator As Mediator)
MyBase.New(mediator)
End Sub
Public Sub SendMessage(ByVal message As String)
Console.WriteLine("Colleague1 sending message: " & message)
mediator.SendMessage(message, Me)
End Sub
Public Overrides Sub ReceiveMessage(ByVal message As String)
Console.WriteLine("Colleague1 received message: " & message)
End Sub
End Class
Public Class ConcreteColleague2
Inherits Colleague
Public Sub New(ByVal mediator As Mediator)
MyBase.New(mediator)
End Sub
Public Sub SendMessage(ByVal message As String)
Console.WriteLine("Colleague2 sending message: " & message)
mediator.SendMessage(message, Me)
End Sub
Public Overrides Sub ReceiveMessage(ByVal message As String)
Console.WriteLine("Colleague2 received message: " & message)
End Sub
End Class
Public Class ConcreteMediator
Implements Mediator
Private colleague1 As ConcreteColleague1
Private colleague2 As ConcreteColleague2
Public Sub SetColleague1(ByVal colleague As ConcreteColleague1)
colleague1 = colleague
End Sub
Public Sub SetColleague2(ByVal colleague As ConcreteColleague2)
colleague2 = colleague
End Sub
Public Sub SendMessage(ByVal message As String, ByVal colleague As Colleague) Implements Mediator.SendMessage
If colleague Is colleague1 Then
colleague2.ReceiveMessage(message)
Else
colleague1.ReceiveMessage(message)
End If
End Sub
End Class
Module MediatorPatternDemo
Sub Main()
Dim mediator As New ConcreteMediator()
Dim colleague1 As New ConcreteColleague1(mediator)
Dim colleague2 As New ConcreteColleague2(mediator)
mediator.SetColleague1(colleague1)
mediator.SetColleague2(colleague2)
colleague1.SendMessage("Hello from Colleague1")
colleague2.SendMessage("Hello from Colleague2")
End Sub
End Module
まとめ
Mediatorパターンは、複数のオブジェクト間の複雑な相互依存を管理し、メンテナンスを容易にするための重要なデザインパターンです。
システムの柔軟性を高め、拡張性のある設計が可能になります。
上記のように、Java、C++、C#、VB.NETそれぞれでの実装方法を通して、このパターンの有用性を確認できました。
オブジェクト指向プログラミングにおけるGoFの23のデザインパターン
デザインパターンは、ソフトウェア設計の問題を効果的に解決するための再利用可能な解決策です。本記事では、GoF(Gang ...