Mediator - Design Pattern

Mediator - Design Pattern

Software Architecture Simplified

Jul 17, 2022·

3 min read

Objective 🎯

Reduce chaotic dependencies between objects by restricting direct communication and forcing objects to collaborate only via a mediator object.

Type ✅

✔️Behavioral: Describes how objects interact/communicate between themselves.

❌Creational: Describes how to instantiate an object without large and complex.

❌Structural: Describes how objects/classes are composed to form larger structures.

UML 📐

image.png

Participants 🔗

• Mediator:

  • Defines an interface for communicating with Colleague objects

• ConcreteMediator:

  • Knows and maintains its colleagues
  • Coordinate Colleague objects

• Colleague:

  • Knows its Mediator object
  • Use Mediator object to communicate with other Colleague object

Sample Code 🎮

Structural Example 🏛️

image.png

public static class MediatorStructural
    {
        public static void Execute()
        {
            ConcreteMediator lConcreteMediator = new ConcreteMediator();

            ConcreteColleague1 lConcreteColleague1 = new ConcreteColleague1(lConcreteMediator);
            ConcreteColleague2 lConcreteColleague2 = new ConcreteColleague2(lConcreteMediator);

            lConcreteMediator.Colleague1 = lConcreteColleague1;
            lConcreteMediator.Colleague2 = lConcreteColleague2;

            lConcreteColleague1.Send("How are you?");
            lConcreteColleague2.Send("Fine, thanks");
        }
    }

    public abstract class Mediator
    {
        public abstract void Send(string message,
            Colleague colleague);
    }

    public class ConcreteMediator : Mediator
    {
        private ConcreteColleague1 _ConcreteColleague1;
        private ConcreteColleague2 _ConcreteColleague2;

        public ConcreteColleague1 Colleague1
        {
            set { _ConcreteColleague1 = value; }
        }

        public ConcreteColleague2 Colleague2
        {
            set { _ConcreteColleague2 = value; }
        }

        public override void Send(string prMessage, Colleague prColleague)
        {
            if (prColleague == _ConcreteColleague1)
            {
                Console.WriteLine("Mediator is sending message to Colleague2");
                _ConcreteColleague2.Notify(prMessage);
            }
            else
            {
                Console.WriteLine("Mediator is sending message to Colleague1");
                _ConcreteColleague1.Notify(prMessage);
            }
        }
    }

    public abstract class Colleague
    {
        protected Mediator _Mediator;

        public Colleague(Mediator prMediator)
        {
            _Mediator = prMediator;
        }
    }

    public class ConcreteColleague1 : Colleague
    {
        public ConcreteColleague1(Mediator prMediator)
            : base(prMediator) { }

        public void Send(string prMessage)
        {
            _Mediator.Send(prMessage, this);
        }

        public void Notify(string prMessage)
        {
            Console.WriteLine("Colleague1 gets message \"" + prMessage + "\"");
        }
    }

    public class ConcreteColleague2 : Colleague
    {
        public ConcreteColleague2(Mediator prMediator)
            : base(prMediator) { }

        public void Send(string prMessage)
        {
            _Mediator.Send(prMessage, this);
        }

        public void Notify(string prMessage)
        {
            Console.WriteLine("Colleague2 gets message: " + prMessage);
        }
    }

Output

image.png

Real-world Example 🔥

image.png

public static class MediatorPractical
    {
        public static void Execute()
        {
            Chatroom lChatroom = new Chatroom();

            // Create participants
            Participant lGeorge = new Teacher("George");
            Participant lPaul = new Studant("Paul");
            Participant lRingo = new Studant("Ringo");
            Participant lJohn = new Studant("John");

            // Register them
            lChatroom.Register(lGeorge);
            lChatroom.Register(lPaul);
            lChatroom.Register(lRingo);
            lChatroom.Register(lJohn);

            // Chatting participants
            lPaul.Send("George", "Hi Teacher!");
            lGeorge.Send("Paul", "Hi Paul, how are you?");
            lPaul.Send("George", "I am good thanks");
            lGeorge.Send("John", "John, did you finish your homework?");
            lJohn.Send("George", "Hi Teacher, yes I did");
            lGeorge.Send("Ringo", "Ringo, what about you?");
            lRingo.Send("George", "Hi Teacher, I finished as well");
        }
    }

    public abstract class AbstractChatroom
    {
        public abstract void Register(Participant prParticipant);
        public abstract void Send(string prFrom, string prTo, string prMessage);
    }

    public class Chatroom : AbstractChatroom
    {
        private Dictionary<string, Participant> _Participants = new Dictionary<string, Participant>();

        public override void Register(Participant prParticipant)
        {
            if (!_Participants.ContainsValue(prParticipant))
                _Participants[prParticipant._Name] = prParticipant;

            prParticipant._Chatroom = this;
        }

        public override void Send(string prFrom, string prTo, string prMessage)
        {
            Participant lParticipant = _Participants[prTo];

            if (lParticipant != null)
                lParticipant.Receive(prFrom, prMessage);
        }
    }

    public class Participant
    {
        public Chatroom _Chatroom { get; set; }
        public string _Name { get; set; }

        public Participant(string prName)
        {
            _Name = prName;
        }

        public void Send(string prTo, string prMessage)
        {
            _Chatroom.Send(_Name, prTo, prMessage);
        }

        public virtual void Receive(string prFrom, string prMessage)
        {
            Console.WriteLine("{0} to {1}: '{2}'", prFrom, _Name, prMessage);
        }
    }

    public class Teacher : Participant
    {
        public Teacher(string prName) : base(prName) { }

        public override void Receive(string prFrom, string prMessage)
        {
            Console.Write("To a Teacher: ");
            base.Receive(prFrom, prMessage);
        }
    }

    public class Studant : Participant
    {
        public Studant(string prName) : base(prName) { }

        public override void Receive(string prFrom, string prMessage)
        {
            Console.Write("To a Studant: ");
            base.Receive(prFrom, prMessage);
        }
    }

Output

image.png

Source Code 🎲

github.com/VictorLins/DesignPatterns

Did you find this article valuable?

Support Victor Lins by becoming a sponsor. Any amount is appreciated!