一、概述
在軟件開發中,我們有時會碰上許多對象互相聯系互相交互的情況,對象之間存在復雜的引用關系,當需求更改時,對系統進行修改將會非常困難。為了對系統的對象進行解耦,可以引入一個間接層來管理對象之間的關系,這就是中介者模式。
二、中介者模式
用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯示地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。其結構圖如下:

Mediator作為中介者定義一個接口用於與各Colleague對象交互。
ConcreteMediator實現了Mediator接口,作為具體的中介者通過協調各Colleague對象實現協作行為。
每一個Colleague中都引用Mediator對象,通過該對象實現與其他Colleague的交互。
中介者模式利用Mediator實現了Colleague間的松耦合,但由於Mediator將Colleague間的復雜引用關系變成了Mediator的復雜性,隨着邏輯的復雜化,Mediator對象可能會變得相當復雜。因此在實際使用中要慎用,以免Mediator的復雜性抵消中介者模式帶來的好處。
三、示例
我們以一個汽車遙控器為例介紹一下中介者模式。例子比較簡單沒必要使用中介者模式,但可以以此了解一下該模式的使用方法。
首先定義Colleague。
1 public abstract class PlayerControllerButton 2 { 3 protected PlayerController _controller; 4 public bool Enable { get; set; } 5 6 public PlayerControllerButton(PlayerController controller) 7 { 8 _controller = controller; 9 } 10 11 public virtual void Click() 12 { 13 _controller.ClickButton(this); 14 } 15 } 16 17 public class StartButton : PlayerControllerButton 18 { 19 public StartButton(PlayerController controller) 20 : base(controller) 21 { 22 controller.Register(this); 23 } 24 } 25 26 public class StopButton : PlayerControllerButton 27 { 28 public StopButton(PlayerController controller) 29 : base(controller) 30 { 31 controller.Register(this); 32 } 33 } 34 35 public class PauseButton : PlayerControllerButton 36 { 37 public PauseButton(PlayerController controller) 38 : base(controller) 39 { 40 controller.Register(this); 41 } 42 }
接着定義Mediator。
1 public class PlayerController 2 { 3 private StartButton _startButton; 4 private StopButton _stopButton; 5 private PauseButton _pauseButton; 6 7 public PlayerController() 8 { 9 } 10 11 public void Register(PlayerControllerButton button) 12 { 13 if (button.GetType().ToString() == "DesignPattern.Mediator.StartButton") 14 { 15 _startButton = button as StartButton; 16 } 17 else if (button.GetType().ToString() == "DesignPattern.Mediator.StopButton") 18 { 19 _stopButton = button as StopButton; 20 } 21 else if (button.GetType().ToString() == "DesignPattern.Mediator.PauseButton") 22 { 23 _pauseButton = button as PauseButton; 24 } 25 } 26 27 public void ClickButton(PlayerControllerButton button) 28 { 29 if (button == _startButton) 30 { 31 _startButton.Enable = true; 32 _stopButton.Enable = false; 33 _pauseButton.Enable = false; 34 } 35 else if (button == _stopButton) 36 { 37 _startButton.Enable = false; 38 _stopButton.Enable = true; 39 _pauseButton.Enable = false; 40 } 41 else if (button == _pauseButton) 42 { 43 _startButton.Enable = false; 44 _stopButton.Enable = false; 45 _pauseButton.Enable = true; 46 } 47 } 48 49 public void DisplayButtonState() 50 { 51 Console.WriteLine("StartButton is {0}, StopButton is {1}, PauseButton is {2}", _startButton.Enable, _stopButton.Enable, _pauseButton.Enable); 52 } 53 }
