الگوی Mediator

الگوی Mediator(میانجی،کارگردان) در دسته الگوهای رفتاری قرار دارد. تعریف یک شی که چگونگی تعامل مجموعه ای از اشیاء با یکدیگر را کپسوله سازی میکند. Mediator، با حفظ اشیاء از اشاره به یکدیگر به صراحت، باعث می شود که اتصال شل ایجاد شود، و به شما اجازه می دهد که تعامل خود را به طور مستقل تغییر دهید. به عبارت دیگر تعریف شی واسطه برای جلوگیری از ارتباط مستقیم اشیا مختلف به یکدیگر و مدیریت روابط بین آنها.UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از:میانجی Mediator ( واسط چت روم در مثال دنیای واقعی IChatroom): یک واسط(interface) برای برقراری ارتباط با اشیاء همکار تعریف می کند.( واسطی است که ساختار شی میانجی را تعریف می کند. )میانجی سفت ConcreteMediator (کلاس چت روم Chatroom) : رفتار همکار را با هماهنگ کردن اشیاء همکار پیاده سازی می کند. همکاران خود را می داند و نگه می دارد.به عبارت دیگر یک میانجی واقعی یا کلاسی است که واسطه Mediator را پیاده سازی کرده است. این کلاس از همه اشیاء درون مجموعه خبر داشته و ارجاعی به آن‌ها در اختیار دارد.همچنین رفتار مولفه را در ارتباط اشیاء با یکدیگر تعریف می کند. کلاس های همکار Colleague classes (شرکت کننده Participant):هر کلاس همکارش شیء واسطه را می داند هر یك از همكاران با واسطه خود ارتباط برقرار می كند هر زمان كه با همكار دیگری ارتباط برقرار می كندبه عبارت دیگر همکار سفت ConcreteColleagure1 و ConcreteColleagure1 کلاس هایی هستند که واسط Colleague را پیاده سازی کرده اند. تمام این کلاس ها از وجود Mediator آگاه بوده و ارجاع به آن در اختیار دارد.این کلاس ها تغییرات خود را به Mediator اطلاع داده و برای ارتباط با سایر کنترلر ها (ارسال چیزی به آنها یا دستکاری آنها) از Mediator استفاده کرده و انجام این کار را از Mediator درخواست می کند. از آن جایی که شی Mediator ارجاعی به تمام اشیاء موجود در مجموعه در اختیار داشته و رفتار مجموعه را تعریف می کند، میداند هنگام دریافتدر خواست هر شعر چه باید بکند و به دنبال آن چه که شی ای را باید تغییر بدهد. ساختار کلی کدالگوی میانجی را نشان می دهد که ارتباط بین اشیاء مختلف و انواع شیء را به آسانی ارتباط سست ( loosely coupled )می دهد.Mediator یک قطب مرکزی است که طی آن همه تعامل باید انجام شود. using System; namespace DoFactory.GangOfFour.Mediator.Structural { /// <summary> /// MainApp startup class for Structural /// Mediator Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { ConcreteMediator m = new ConcreteMediator (); ConcreteColleague1 c1 = new ConcreteColleague1 (m); ConcreteColleague2 c2 = new ConcreteColleague2 (m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send ("How are you?"); c2.Send ("Fine, thanks"); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Mediator' abstract class /// </summary> abstract class Mediator { public abstract void Send (string message, Colleague colleague); } /// <summary> /// The 'ConcreteMediator' class /// </summary> class ConcreteMediator : Mediator { private ConcreteColleague1 _colleague1; private ConcreteColleague2 _colleague2; public ConcreteColleague1 Colleague1 { set { _colleague1 = value; } } public ConcreteColleague2 Colleague2 { set { _colleague2 = value; } } public override void Send (string message, Colleague colleague) { if (colleague == _colleague1) { _colleague2.Notify (message); } else { _colleague1.Notify (message); } } } /// <summary> /// The 'Colleague' abstract class /// </summary> abstract class Colleague { protected Mediator mediator; // Constructor public Colleague (Mediator mediator) { this.mediator = mediator; } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class ConcreteColleague1 : Colleague { // Constructor public ConcreteColleague1 (Mediator mediator) : base (mediator) { } public void Send (string message) { mediator.Send (message, this); } public void Notify (string message) { Console.WriteLine ("Colleague1 gets message: " + message); } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class ConcreteColleague2 : Colleague { // Constructor public ConcreteColleague2 (Mediator mediator) : base (mediator) { } public void Send (string message) { mediator.Send (message, this); } public void Notify (string message) { Console.WriteLine ("Colleague2 gets message: " + message); } } } OutputColleague2 gets message : How are you?Colleague1 gets message : Fine, thanksیاabstract class Mediator { protected ConcreteColleague1 colleague1; protected ConcreteColleague2 colleague2; public Mediator(ConcreteColleague1 colleague1, ConcreteColleague2 colleague2) { this.colleague1 = colleague1; this.colleague2 = colleague2; } public abstract void NotifyChange(string message, Colleague colleague); } class ConcreteMediator: Mediator { public ConcreteMediator(ConcreteColleague1 colleague1, ConcreteColleague2 colleague2): base(colleague1, colleague2) { } public override void NotifyChange(string message, Colleague colleague) { if (colleague == colleague1) { colleague2.HerReceive(message); } else { colleague1.HisReceive(message); } } } abstract class Colleague { protected Mediator mediator; public void SetMediator(Mediator mediator) { this.mediator = mediator; } public virtual void Send(string message) { mediator.NotifyChange(message, this); } } class ConcreteColleague1: Colleague { public override void Send(string message) { Console.WriteLine("Colleague1: sending '" + message + "' to colleague2"); base.Send(message); } public void HisReceive(string message) { Console.WriteLine("Colleague1 received: " + message); } } class ConcreteColleague2: Colleague { public override void Send(string message) { Console.WriteLine("Colleague2: sending '" + message + "' to colleague1"); base.Send(message); } public void HerReceive(string message) { Console.WriteLine("Colleague2 received: " + message); } } class MainApp { static void Main() { var c1 = new ConcreteColleague1(); var c2 = new ConcreteColleague2(); var m = new ConcreteMediator(c1, c2); c1.SetMediator(m); c2.SetMediator(m); c1.Send("How are you?"); c2.Send("Fine, thanks"); Console.ReadKey(); } } /* OUTPUT:Colleague1: sending 'How are you?' to colleague2Colleague2 received: How are you?Colleague2: sending 'Fine, thanks' to colleague1Colleague1 received: Fine, thanks*/مثال دنیای واقعی الگوی میانجی را تسهیل ارتباط سست ( loosely coupled ) بین شرکت کنندگان مختلف ثبت نام با Chatroom نشان می دهد. Chatroom قطب مرکزی است که طی آن همه ارتباطات اتفاق می افتد. در این مرحله تنها ارتباط یک به یک در Chatroom انجام می شود، اما برای تغییر به یک به چند، بی اهمیت است. using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Mediator.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Mediator Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // Create chatroom Chatroom chatroom = new Chatroom (); // Create participants and register them Participant George = new Beatle ("George"); Participant Paul = new Beatle ("Paul"); Participant Ringo = new Beatle ("Ringo"); Participant John = new Beatle ("John"); Participant Yoko = new NonBeatle ("Yoko"); chatroom.Register (George); chatroom.Register (Paul); chatroom.Register (Ringo); chatroom.Register (John); chatroom.Register (Yoko); // Chatting participants Yoko.Send ("John", "Hi John!"); Paul.Send ("Ringo", "All you need is love"); Ringo.Send ("George", "My sweet Lord"); Paul.Send ("John", "Can't buy me love"); John.Send ("Yoko", "My sweet love"); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Mediator' abstract class /// </summary> abstract class AbstractChatroom { public abstract void Register (Participant participant); public abstract void Send ( string from, string to, string message); } /// <summary> /// The 'ConcreteMediator' class /// </summary> class Chatroom : AbstractChatroom { private Dictionary<string, Participant> _participants = new Dictionary<string, Participant> (); public override void Register (Participant participant) { if (!_participants.ContainsValue (participant)) { _participants[participant.Name] = participant; } participant.Chatroom = this; } public override void Send ( string from, string to, string message) { Participant participant = _participants[to]; if (participant != null) { participant.Receive (from, message); } } } /// <summary> /// The 'AbstractColleague' class /// </summary> class Participant { private Chatroom _chatroom; private string _name; // Constructor public Participant (string name) { this._name = name; } // Gets participant name public string Name { get { return _name; } } // Gets chatroom public Chatroom Chatroom { set { _chatroom = value; } get { return _chatroom; } } // Sends message to given participant public void Send (string to, string message) { _chatroom.Send (_name, to, message); } // Receives message from given participant public virtual void Receive ( string from, string message) { Console.WriteLine ("{0} to {1}: '{2}'", from, Name, message); } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class Beatle : Participant { // Constructor public Beatle (string name) : base (name) { } public override void Receive (string from, string message) { Console.Write ("To a Beatle: "); base.Receive (from, message); } } /// <summary> /// A 'ConcreteColleague' class /// </summary> class NonBeatle : Participant { // Constructor public NonBeatle (string name) : base (name) { } public override void Receive (string from, string message) { Console.Write ("To a non-Beatle: "); base.Receive (from, message); } } } OutputTo a Beatle : Yoko to John: 'Hi John!'To a Beatle : Paul to Ringo: 'All you need is love'To a Beatle : Ringo to George: 'My sweet Lord'To a Beatle : Paul to John: 'Can't buy me love 'To a non-Beatle: John to Yoko: 'My sweet love 'منبع