Design patterns in C# – part 19 (Mediator pattern)

Role

The Mediator pattern is there to enable objects to communicate without knowing each other’s identities. It also encapsulates a protocol that objects can follow.

Design

MediatorPattern

Implementation

  • Mediator -> MailingListModerator
  • Colleague -> MailWithCopyOwnMessages, MailWithoutCopyOwnMessages (IMail implementation)
using System;

namespace MediatorPattern
{
    public class TestMediatorPattern
    {
        public static void Main(string[] args)
        {
            var moderator = new MailingListModerator();

            var jackMail = new MailWithCopyOwnMessages(moderator, "jacek@mail.com");
            var tomMail = new MailWitoutCopyOwnMessages(moderator, "tom@hotmail.com");
            var michaelMail = new MailWithCopyOwnMessages(moderator, "michael@sunmail.com");

            jackMail.Send("Meeting on Saturday, please all ack");
            tomMail.Send("Ack");

            moderator.Block(tomMail.Receive);

            jackMail.Send("Still waiting some Acks");
            michaelMail.Send("Ack");

            moderator.Unblock(tomMail.Receive);
            jackMail.Send("Thanks all");
        }
    }

    public class MailingListModerator
    {
        #region Delegates

        public delegate void Callback(string message, string form);

        #endregion

        private event Callback Respond;

        public void SignOn(Callback method)
        {
            this.Respond += method;
        }

        public void Block(Callback method)
        {
            this.Respond -= method;
        }

        public void Unblock(Callback method)
        {
            this.Respond += method;
        }

        public void Send(string message, string from)
        {
            if (this.Respond != null)
            {
                this.Respond(message, from);
            }
            Console.WriteLine();
        }
    }

    public interface IMail
    {
        void Receive(string message, string from);
        void Send(string message);
    }

    public class MailWithCopyOwnMessages : IMail
    {
        private readonly MailingListModerator _mailingListModerator;
        protected string _name;

        public MailWithCopyOwnMessages(MailingListModerator mailingListModerator, string name)
        {
            this._mailingListModerator = mailingListModerator;
            this._mailingListModerator.SignOn(this);
            this._name = name;
        }

        #region IMail Members

        public virtual void Receive(string message, string from)
        {
            Console.WriteLine("{0} received from {1}:\n\t{2}", this._name, from, message);
        }

        public void Send(string message)
        {
            Console.WriteLine("Send (From {0}):\n\t{1}", this._name, message);
            this._mailingListModerator.Send(message, this._name);
        }

        #endregion
    }

    public class MailWitoutCopyOwnMessages : MailWithCopyOwnMessages
    {
        public MailWitoutCopyOwnMessages(MailingListModerator mailingListModerator, string name)
            : base(mailingListModerator, name)
        {
        }

        public override void Receive(string message, string from)
        {
            if (!(String.Equals(from, _name)))
            {
                Console.WriteLine("{0} received from {1}: \n\t{2}", _name, from, message);
            }
        }
    }
}

OUTPUT:

Send (From jacek@mail.com):
Meeting on Saturday, please all ack
jacek@mail.com received from jacek@mail.com:
Meeting on Saturday, please all ack
tom@hotmail.com received from jacek@mail.com:
Meeting on Saturday, please all ack
michael@sunmail.com received from jacek@mail.com:
Meeting on Saturday, please all ack
Send (From tom@hotmail.com):
Ack
jacek@mail.com received from tom@hotmail.com:
Ack
michael@sunmail.com received from tom@hotmail.com:
Ack
Send (From jacek@mail.com):
Still waiting some Acks
jacek@mail.com received from jacek@mail.com:
Still waiting some Acks
michael@sunmail.com received from jacek@mail.com:
Still waiting some Acks
Send (From michael@sunmail.com):
Ack
jacek@mail.com received from michael@sunmail.com:
Ack
michael@sunmail.com received from michael@sunmail.com:
Ack
Send (From jacek@mail.com):
Thanks all
jacek@mail.com received from jacek@mail.com:
Thanks all
michael@sunmail.com received from jacek@mail.com:
Thanks all
tom@hotmail.com received from jacek@mail.com:
Thanks all

Use when

  • Objects communicate in well-structured but potentially complex ways.
  • The objects identities should be protected even though they communicate.
  • Some object behavior can be grouped and customized.

Bibliography

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s