設計模式之美:Mediator(中介者)


索引

意圖

用一個中介對象來封裝一系列的對象交互。

中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。

Define an object that encapsulates how a set of objects interact.

Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

結構

一個典型的對象結構:

參與者

Mediator

  • 中介者定義一個接口用於與各同事對象通信。

ConcreteMediator

  • 具體中介者通過協調各同事對象實現協作行為。
  • 了解並維護它的各個同事。

Colleague

  • 每一個同事類都知道它的中介者。
  • 每一個同事對象在需與其他同事通信時,與它的中介者通信。

適用性

在以下情況下可以使用 Mediator 模式:

  • 一組對象定義良好但是使用復雜的通信方式。產生的相互依賴關系結構混亂且難以理解。
  • 一個對象引用其他很多對象並且直接與這些對象通信,導致難以復用該對象。
  • 想定制一個分布在多個類中的行為,而又不想生成太多的子類。

效果

  • 減少了子類的生成。
  • 將各個同事類解耦。
  • 它簡化了對象協議。
  • 它對對象如何協作進行了抽象。
  • 它使控制集中化。

相關模式

  • Facade 模式與 Mediator 模式的不同之處在於它是對一個對象子系統進行抽象,從而提供了一個更為方便的接口。它的協議是單向的,即 Facade 對象對這個子系統類提出要求,但反之則不行。Mediator 提供了各 Colleague 對象不支持或不能支持的協作行為,而協議是多向的。
  • Colleague 可以使用 Observer 模式與 Mediator 通信。

實現

實現方式(一):Mediator 模式結構樣式代碼。

 Colleague-Mediator 的通信中,當一個感興趣的事件發生時,Colleague 必須與其 Mediator 通信。

一種方式是使用 Observer 模式,將 Mediator 實現為一個 Observer,各 Colleague 作為 Subject。

另一種方式是在 Mediator 中定義一個特殊的通知接口,各 Colleague 在通信時直接調用該接口。

  1 namespace MediatorPattern.Implementation1
  2 {
  3   public abstract class Colleague
  4   {
  5     protected Mediator _mediator;
  6 
  7     public Colleague(Mediator mediator)
  8     {
  9       _mediator = mediator;
 10     }
 11 
 12     public abstract void Send(string message);
 13     public abstract void Notify(string message);
 14   }
 15 
 16   public abstract class Mediator
 17   {
 18     public abstract void SendMessage(Colleague sender, string message);
 19   }
 20 
 21   public class ConcreteMediator : Mediator
 22   {
 23     private ConcreteColleague1 _colleague1;
 24     private ConcreteColleague2 _colleague2;
 25 
 26     public ConcreteColleague1 Colleague1
 27     {
 28       set { _colleague1 = value; }
 29     }
 30 
 31     public ConcreteColleague2 Colleague2
 32     {
 33       set { _colleague2 = value; }
 34     }
 35 
 36     public override void SendMessage(Colleague sender, string message)
 37     {
 38       if (sender == _colleague1)
 39       {
 40         _colleague2.Notify(message);
 41       }
 42       else if (sender == _colleague2)
 43       {
 44         _colleague1.Notify(message);
 45       }
 46     }
 47   }
 48 
 49   public class ConcreteColleague1 : Colleague
 50   {
 51     public ConcreteColleague1(Mediator mediator)
 52       : base(mediator)
 53     {
 54     }
 55 
 56     public override void Send(string message)
 57     {
 58       _mediator.SendMessage(this, message);
 59     }
 60 
 61     public override void Notify(string message)
 62     {
 63       Console.WriteLine("Colleague1 gets message: " + message);
 64     }
 65   }
 66 
 67   public class ConcreteColleague2 : Colleague
 68   {
 69     public ConcreteColleague2(Mediator mediator)
 70       : base(mediator)
 71     {
 72     }
 73 
 74     public override void Send(string message)
 75     {
 76       _mediator.SendMessage(this, message);
 77     }
 78 
 79     public override void Notify(string message)
 80     {
 81       Console.WriteLine("Colleague2 gets message: " + message);
 82     }
 83   }
 84 
 85   public class Client
 86   {
 87     public void TestCase1()
 88     {
 89       var mediator = new ConcreteMediator();
 90 
 91       var colleague1 = new ConcreteColleague1(mediator);
 92       var colleague2 = new ConcreteColleague2(mediator);
 93 
 94       mediator.Colleague1 = colleague1;
 95       mediator.Colleague2 = colleague2;
 96 
 97       colleague1.Send("How are you?");
 98       colleague2.Send("Fine, Thank you!");
 99     }
100   }
101 }

設計模式之美》為 Dennis Gao 發布於博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM