概要:
複数のオブジェクト間の相互作用を仲介オブジェクトで統括する。このアプローチにより、オブジェクト同士の直接的な参照が不要となり、結合度を低減しつつ、相互作用の変更を柔軟に行えるようになる。
適用場面:
- 複数のオブジェクトが複雑なルールで通信しており、依存関係が絡み合って理解が困難な場合
- オブジェクトが多数の他のオブジェクトを直接参照し、再利用性が低下している場合
- 複数のクラスに分散した振る舞いをカスタマイズしたいが、サブクラスを大量に作成したくない場合
クラス図: (図の説明は省略)
コード例:
- 中心となる仲介クラスの定義
public abstract class CentralCoordinator
{
public abstract void RouteMessage(string content, Participant sender);
}
- 参加者基底クラスの定義
public abstract class Participant
{
protected CentralCoordinator coordinator;
public Participant(CentralCoordinator coordinator)
{
this.coordinator = coordinator;
}
public abstract void Receive(string message);
}
- 具体的な仲介ロジックの実装
public class SystemManager : CentralCoordinator
{
private Participant userA;
private Participant userB;
public void RegisterUserA(Participant participant)
{
userA = participant;
}
public void RegisterUserB(Participant participant)
{
userB = participant;
}
public override void RouteMessage(string content, Participant sender)
{
if (sender == userA)
{
// ユーザーA→ユーザーBへのメッセージルーティング
userB.Receive($"[経由] {content}");
}
else
{
// ユーザーB→ユーザーAへのメッセージルーティング
userA.Receive($"[経由] {content}");
}
}
}
- 実際の参加者クラス
public class UserA : Participant
{
public UserA(CentralCoordinator coordinator) : base(coordinator) { }
public void Send(string message)
{
coordinator.RouteMessage(message, this);
}
public override void Receive(string message)
{
Console.WriteLine("ユーザーA: 受信内容 - " + message);
}
}
public class UserB : Participant
{
public UserB(CentralCoordinator coordinator) : base(coordinator) { }
public void Send(string message)
{
coordinator.RouteMessage(message, this);
}
public override void Receive(string message)
{
Console.WriteLine("ユーザーB: 受信内容 - " + message);
}
}
- 実行例
static void Main()
{
var manager = new SystemManager();
var userA = new UserA(manager);
var userB = new UserB(manager);
manager.RegisterUserA(userA);
manager.RegisterUserB(userB);
userA.Send("システムの利用ありがとうございます");
userB.Send("こちらこそ、いつもお世話になっております");
}
要点:
このパターンは、オブジェクト間の通信を仲介クラスで集中管理することで、複雑な相互作用を簡潔に表現できる。特にシステムのスケーラビリティを重視する場面で有効である。