Wednesday, July 22, 2009

Mediator pattern implementation using C# 3.5 delegates

The mediator pattern provides a unified interface to a set of interfaces in a subsystem. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior. With the mediator pattern communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.

Mediator design pattern deals with communication. In this post I am going to demonstrate a chat room application where users send and receive messages when signed into the room. Users who are not interested in receiving messages can make their status 'Away' so that they will not receive the messages. So clearly the moderation process here is performing part of the role of the Mediator pattern is establishing a communication protocol and content filter. The other part keeping users unaware of each other is inherently part of the chat room.

ChatRoomMediator is playing a role of mediator which has all the preferences of sign on, logoff, away or available statuses. ConcreteUser is a class who send and receives messages in the chat room.

ChatRoomMediator class

public class ChatRoomMediator

{

Action<string, BaseUser> Publish;

public void SignIn(BaseUser user)

{

Publish += user.Recieve;

}

public void LogOff(BaseUser user)

{

Publish -= user.Recieve;

}

public void Busy(BaseUser user)

{

Publish -= user.Recieve;

}

public void Available(BaseUser user)

{

Publish += user.Recieve;

}

public void SendToAll(string message, BaseUser user)

{

Publish(message, user);

Console.WriteLine("***----****");

}

}

User class implementation

public abstract class BaseUser

{

public string FirstName { get; set; }

public string LastName { get; set; }

public ChatRoomMediator Mediator { get; private set; }

public BaseUser(ChatRoomMediator mediator)

{

Mediator = mediator;

}

public abstract void Send(string message);

public void Recieve(string message, BaseUser user)

{

if(!(string.Compare(user.FirstName, this.FirstName) == 0 && string.Compare(user.LastName, this.LastName) == 0))

Console.WriteLine(String.Format("{0} {1} Recieved :{2} from {3} {4}", this.FirstName, this.LastName, message, user.FirstName, user.LastName));

}

}

public class ConcreteUser : BaseUser

{

public ConcreteUser(ChatRoomMediator mediator, string firstName, string lastName)

: base(mediator)

{

FirstName = firstName;

LastName = lastName;

}

public override void Send(string message)

{

Console.WriteLine(String.Format("{0} {1}: {2}", this.FirstName, this.LastName, message));

Console.WriteLine("-------------------------------------------");

Mediator.SendToAll(message, this);

}

}

Client code

static void Main(string[] args)

{

ChatRoomMediator __Mediator = new ChatRoomMediator();

ConcreteUser __User1 = new ConcreteUser(__Mediator, "Prajeesh", "Prathap");

ConcreteUser __User2 = new ConcreteUser(__Mediator, "Steve", "Micheal");

ConcreteUser __User3 = new ConcreteUser(__Mediator, "David", "Thompson");

ConcreteUser __User4 = new ConcreteUser(__Mediator, "Maria", "Johnson");

__Mediator.SignIn(__User1);

__Mediator.SignIn(__User2);

__Mediator.SignIn(__User3);

__Mediator.SignIn(__User4);

__User1.Send("Demonstrating the mediator design pattern");

__User2.Send("I'm aware of this pattern, so signing off");

__Mediator.Busy(__User2);

__User3.Send("Ok all other users except the busy ones, get this message");

Console.ReadKey();

}

No comments: