Mediator Design Pattern

In object oriented programming, we have lots of objects interacting with each other. As project continues more objects are introduced and the interaction between these objects becomes dependencies between each other. We modify one object and we have to modify another object too because of dependency with each other.

Mediator design pattern provides easy interaction between a set of objects. Mediator encapsulates all objects information and provides a simple interface by which all the objects interact. Objects does not know about other objects and they only use Mediator object to connect with other objects.

Mediator provides loosely coupling between objects. Its also provides maintainability so that when one object changed we have to modify in only one place Mediator object.

Structure

mediator pattern

Participants

IMediator: Defines an interface which ConcreteMediator implements.

ConcreteMediator: Implements IMediator and encapsulates colleagueObjects information and provides some methods to interact with each other.

IColleague: Defines an interface which all colleague objects implements.

ColleagueObject1-6: Objects want to interacts with each other. Each object knows about the Mediator object. They only interact with Mediator object.

Example

mediator-pattern-example1

In the above diagram, IChatMediator interface contains the AddUser and SendMessageToAllUsers message and ChatMediator implements this interface. All users inherits from the User abstract class. User class have chatMediator and name variables and two methods name SendMessage and ReceiveMessage.

BasicUser have a reference to ChatMediator class and in the send message method, it calls the SendMessageToAllUsers method to send it’s message to all users. BasicUser doesn’t know about the others BasicUsers and PremiumUsers.

Below is the implementation of above diagram in C#.


    class Program
    {
        static void Main(string[] args)
        {
            IChatMediator chatMediator = new ChatMediator();
            
            //3 users are online;
            User ryan = new BasicUser(chatMediator, "Ryan");
            User michael = new PremiumUser(chatMediator, "Michael");
            User james = new PremiumUser(chatMediator, "James");
            chatMediator.AddUser(ryan);
            chatMediator.AddUser(michael);
            chatMediator.AddUser(james);


            //dana added to the chat room
            User dana = new BasicUser(chatMediator, "Dana");
            chatMediator.AddUser(dana);
            
            dana.SendMessage("Dana is online.");
            //Basic User: Ryan receive message: Dana is online.
            //Premium User: Michael receive message: Dana is online.
            //Premium User: James receive message: Dana is online.
        }
    }

    public interface IChatMediator
    {
        void AddUser(User user);
        void SendMessageToAllUsers(string message, User currentUsr);
    }

    public class ChatMediator : IChatMediator
    {
        private List<User> users;

        public ChatMediator()
        {
            users = new List<User>();
        }

        public void AddUser(User user)
        {
            users.Add(user);
        }

        public void SendMessageToAllUsers(string message, User currentUsr)
        {
            users.ForEach(w =>
            {
                if (w != currentUsr)    //don't send message to sender
                {
                    w.ReceiveMessage(message);
                }
            });
        }
    }

    public abstract class User
    {
        private IChatMediator chatMediator;
        private string name;

        public User(IChatMediator chatMediator, string name)
        {
            this.chatMediator = chatMediator;
            this.name = name;
        }

        public string Name
        {
            get
            {
                return name;
            }
        }

        public IChatMediator ChatMediator
        {
            get
            {
                return chatMediator;
            }
        }

        public abstract void SendMessage(string message);
        public abstract void ReceiveMessage(string message);
    }

    public class BasicUser : User
    {
        public BasicUser(IChatMediator chatMediator, string name)
            : base(chatMediator, name)
        {
        }

        public override void SendMessage(string message)
        {
            this.ChatMediator.SendMessageToAllUsers(message, this);
        }

        public override void ReceiveMessage(string message)
        {
            Console.WriteLine("Basic User: " + this.Name + " receive message: " + message);
        }
    }

    public class PremiumUser : User
    {
        public PremiumUser(IChatMediator chatMediator, string name)
            : base(chatMediator, name)
        {
        }

        public override void SendMessage(string message)
        {
            this.ChatMediator.SendMessageToAllUsers(message, this);
        }

        public override void ReceiveMessage(string message)
        {
            Console.WriteLine("Premium User: " + this.Name + " receive message: " + message);
        }
    }