Design Pattern - Behavioral Patterns - Mediator Pattern

50 篇文章 0 订阅
37 篇文章 0 订阅

2007

Section 5, Chapter 3


Mediator Pattern


Concept

The Mediator pattern allows groups of objects to communicate in a disassociated manner and encapsulates this communication while keeping the objects loosely coupled. The pattern allows objects to communicate on a one-to-one basis and acts as a proxy between objects to facilitate this communication.


Use

If you have a group of objects that need to communicate in some way, but you don't wish to allow them direct access to one another, then using this pattern would be a way to encapsulate this communication in a single object. You find yourself needing to have several objects of similar types communicate in some way with each other. But often this communication can become too entangled and the methods of communication too deeply coupled or too rigid to make changes easily.


Design

The Mediator pattern has two main classes associated with it: the Mediator and the Colleague. The mediator acts as a go-between to the colleagues and controls which two colleagues communicate.



Illustration



interface IMessageEngine
{
	void Register(MessageThread thread);
	void Send(string from, string to, string message);
}


class MessageEngine : IMessageEngine
{
	private Hashtable _messageThreads = new Hashtable();
	public void Register(MessageThread thread)
	{
		if(!_messageThreads.ContainsKey(thread.Name))
			_messageThreads.Add(thread.Name,thread);
		thread.MessageEngine = this;
	}
	public void Send(string from, string to, string message)
	{
		MessageThread thread = (MessageThread)_messageThreads[to];
		if(thread != null)
			thread.Receive(from, message);
	}
}


abstract class MessageThread
{
	private IMessageEngine _messageEngine;
	.....
	public IMessageEngine MessageEngine
	{
		set{ _messageEngine = value; }
		get{ return _messageEngine; }
	}
	public void Send(string to, string message)
	{
		_messageEngine.Send(_name, to, message);
	}
}


// lack a concrete class implmenting MessageThread here


//Create the message engine which is the mediator
IMessageEngine engine = new MessageEngine();
//instantiate two chat instance message windows
MessageThread imWindow = new IMWindow("Jazzy Jeff");
MessageThread chatWindow = new ChatWindow("Sir Chats-A-Lot");
//Register each chat instance window with the mediator
engine.Register(imWindow);
engine.Register(chatWindow);
//Jazzy Jeff sends a message to Sir Chats-A-Lot
imWindow.Send("Sir Chats-A-Lot","Hey Sir Chats-A-Lot!");
// Sir Chats-A-Lot sends a message back to Jazzy Jeff
chatWindow.Send("Jazzy Jeff","Hey Jazzy!");


Comment: according to the code syntax, it should be C#, however, this sample lacks the implementation of class IMWindow and ChatWindow.


Comment: this implementation only allow peer-to-peer communication.


December 2007

Section 2, Chapter 9




Use

  • There is protocol that is observed between the members of a group.
  • Messages might also be vetted for content.
  • The Mediator pattern makes provisions for more than one mediator.


ColleagueRegisters with a Mediator by supplying a Receive method; issues Send requests to other colleagues via the Mediator.
MediatorBroadcasts sent messages to all signed-on Colleagues using the Respond delegate.



class MediatorPattern {

	// Mediator Pattern Judith Bishop Sept 2007
	/* The Mediator maintains a list of colleagues and specifies the
	 communication methods that it can mediate - in this case, Send.
	 Receive is implemented at Colleague level and called via a delegate
	 supplied by the colleagues to the mediator on sign-on.
	*/

	class Mediator {

		public delegate void Callback(string message, string from);
		Callback respond;

		public void SignOn(Callback method)
		{
			respond += method;
		}

		public void Block(Callback method)
		{
			respond -= method;
		}
		
		public void Unblock(Callback method)
		{
			respond += method;
		}

		// Send is implemented as a broadcast
		public void Send(string message, string from)
		{
			respond(message, from);
			Console.WriteLine();
		}
	}

	class Colleague {
		Mediator mediator;
		protected string name;

		public Colleague(Mediator mediator, string name)
		{
			this.mediator = mediator;
			mediator.SignOn(Receive);
			this.name = name;
		}
		
		public virtual void Receive(string message, string from)
		{
			Console.WriteLine(name +" received from "+from+": " + message);
		}
		
		public void Send(string message)
		{
			Console.WriteLine("Send (From "+name+ "): "+message);
			mediator.Send(message, name);
		}
	}

	class ColleagueB : Colleague {
		public ColleagueB(Mediator mediator,string name) : base(mediator, name) {}

		// Does not get copies of own messages
		public override void Receive(string message, string from)
		{
			if (!String.Equals(from, name))
				Console.WriteLine(name +" received from "+from+": " + message);
		}
	}

	static void Main () {
		ediator m = new Mediator();
		// Two from head office and one from a branch office
		Colleague head1 = new Colleague(m,"John");
		ColleagueB branch1 = new ColleagueB(m,"David");
		Colleague head2 = new Colleague(m,"Lucy");

		head1.Send("Meeting on Tuesday, please all ack");
		branch1.Send("Ack"); // by design does not get a copy
		m.Block(branch1.Receive); // temporarily gets no messages
		head1.Send("Still awaiting some Acks");
		head2.Send("Ack");
		m.Unblock(branch1.Receive); // open again
		head1.Send("Thanks all");
	}
}


Comment: this implemetation allows broadcasting to all the other colleagues..



2016
Chapter 18




Comment: the stupid thing of this implementation is that it does not generalize the concept Friend, which is usually referred as colleague, it defines a class for each friend entity, that means for each entity that wants to join the party, you need a class for it.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值