メディエーター・パターンの理解と実装例

概要:

複数のオブジェクト間の相互作用を仲介オブジェクトで統括する。このアプローチにより、オブジェクト同士の直接的な参照が不要となり、結合度を低減しつつ、相互作用の変更を柔軟に行えるようになる。

適用場面:

  1. 複数のオブジェクトが複雑なルールで通信しており、依存関係が絡み合って理解が困難な場合
  2. オブジェクトが多数の他のオブジェクトを直接参照し、再利用性が低下している場合
  3. 複数のクラスに分散した振る舞いをカスタマイズしたいが、サブクラスを大量に作成したくない場合

クラス図: (図の説明は省略)

コード例:

  1. 中心となる仲介クラスの定義
    public abstract class CentralCoordinator
    {
        public abstract void RouteMessage(string content, Participant sender);
    }
  1. 参加者基底クラスの定義
    public abstract class Participant
    {
        protected CentralCoordinator coordinator;

        public Participant(CentralCoordinator coordinator)
        {
            this.coordinator = coordinator;
        }

        public abstract void Receive(string message);
    }
  1. 具体的な仲介ロジックの実装
    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}");
            }
        }
    }
  1. 実際の参加者クラス
    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);
        }
    }
  1. 実行例
    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("こちらこそ、いつもお世話になっております");
    }

要点:

このパターンは、オブジェクト間の通信を仲介クラスで集中管理することで、複雑な相互作用を簡潔に表現できる。特にシステムのスケーラビリティを重視する場面で有効である。

タグ: デザインパターン メディエーター・パターン オブジェクト指向設計

6月10日 23:02 投稿