在軟體工程領域，中介者模式定義了一箇中介者物件，該物件封裝了系統中物件間的互動方式。 由於它可以在執行時改變程式的行為，這種模式是一種行為型模式 。 通常程式由大量的類組成，這些類中包含程式的邏輯和運算。 然而，當開發者將更多的類加入到程式中之後，類間互動關係可能變得更為複雜，這會使得程式碼變得更加難以閱讀和維護，尤其是在重構的時候。 此外，程式將會變得難以修改，因為對其所做的任何修改都有可能影響到其它幾個類中的程式碼。 在中介者模式中，物件間的通訊過程被封裝在一箇中介者（調解人）物件之中。 物件之間不再直接互動，而是透過調解人進行互動。 這麼做可以減少可互動物件間的依賴，從而降低耦合。 概述 中介者模式是 23 個周知模式（ 即 GoF 設計模式）中的一個，GoF 設計模式旨在提供重複出現的設計問題的解決方案，以編寫靈活和可複用的面向物件軟體。也就是說，使物件更加易於實現、修改、測試和複用。 中介者設計模式可以解決什麼問題？ 避免一組相互互動的物件之間出現緊耦合。 能夠獨立地改變一組物件之間的互動關係而不影響其他物件。 使用直接逐個訪問並更新彼此的方式進行物件間的互動靈活性低，因為這種方式使物件彼此間緊密耦合，導致不可能單獨修改類間互動關係本身，而不影響關係中進行互動的類。並且這種方式會令物件變得無法複用，並且難以測試。 由於緊耦合的物件過多瞭解其他物件的內部細節，這種物件難以實現、修改、測試以及複用。 中介者模式如何解決上述問題？ 定義一個獨立的中介者 調解員 的物件，封裝一組物件之間的互動關係。 物件將自己的互動委託給中介者執行，避免直接與其他物件進行互動。 物件利用中介者物件與其他物件進行間接互動，中介者物件負責控制和協調互動關係，這麼做可使得物件間松耦合。這些物件只訪問中介者，不瞭解其他物件的細節。 另見 UML 類圖和時序圖如下。 定義 中介者模式是為了 定義一個封裝了物件間互動關係的物件。這種方式避免了顯式呼叫其他類，促進了類間的松耦合，並且使得類間互動關係本身可以單獨修改 Gang Of Four。客戶類可以使用中介者向其他客戶類傳送資訊，並且透過中介者引發的事件收到資訊。 結構 UML 類圖和時序圖 在以上 UML 類圖中，類 Colleague1 和 Colleague2 不引用和更新彼此。 相反，它們引用一個通用的 Mediator 介面以實現類間互動的控制和協調 透過 mediate ，這使得它們獨立於類間互動的具體細節。 類 Mediator1 實現了類 Colleague1 和 Colleague2 之間的互動細節。 上述 UML 時序圖 顯示了這些類之間在執行時的互動過程： 在這個例子中，一個 Mediator1 物件 中介，即控制和協調了 Colleague1 和 Colleague2 的物件之間的互動。 如果 Colleague1 的物件需要與 Colleague2 的物件進行互動，例如更新或者同步狀態， Colleague1 呼叫 Mediator1 物件的 mediate this 方法， 以此得到對 Colleague1 物件（自己）的改動資訊，並且在 Colleague2 的物件上執行 action2 方法。 此後， Colleague2 物件呼叫 Mediator1 物件的 mediate this 方法， 得到對 Colleague2 （自己）的修改的資料，並且對 Colleague1 物件呼叫 action1 方法。 類圖 參與者 Mediator 定義 Colleague 物件之間的互動介面。 ConcreteMediator 實現了 Mediator 介面，並且協調 Colleague 物件之間的互動，知道所有的 Colleagues 物件以及其互動目的。 Colleague 定義了透過 Mediator 與其他 Colleague 物件互動的介面。 ConcreteColleague 實現了 Colleague 介面，並且透過它的 Mediator 與其他 Colleague 互動。 範例 C 中介者模式確保了構件之間的松耦合，使得它們不直接呼叫彼此，而是透過中介者呼叫彼此。 在下面的例子中，調解人註冊了所有的構件，然後呼叫了它們的 SetState 方法。 public interface IComponent void SetState object state public class Component1 IComponent public void SetState object state throw new NotImplementedException public class Component2 IComponent public void SetState object state throw new NotImplementedException Mediates the common tasks public class Mediator public IComponent Component1 get set public IComponent Component2 get set public void ChangeState object state thisComponent1SetState state thisComponent2SetState state 一個聊天室，或者一個需要客戶彼此間每次傳送訊息之後執行動作的系統（對聊天室來說就是每個人之間傳送訊息）可以使用中介者模式。但實際上對聊天室使用中介者模式只在包含遠端功能時有用。 原生的套接字不允許委託回呼函式（即透過中介者類訂閱的 MessageReceived 事件）。 public delegate void MessageReceivedEventHandler string message string from public class Mediator public event MessageReceivedEventHandler MessageReceived public void Send string message string from if MessageReceived null ConsoleWriteLine Sending 0 from 1 message from MessageReceived message from public class Person private Mediator _mediator public string Name get set public Person Mediator mediator string name Name name _mediator mediator _mediatorMessageReceived new MessageReceivedEventHandler Receive private void Receive string message string from if from Name ConsoleWriteLine 0 received 1 from 2 Name message from public void Send string message _mediatorSend message Name Java 在以下示例中，一箇中介者物件控制了三個互相互動的按鈕的狀態，為此它有設定狀態的三個方法：book view 和 search 。 當相應的按鈕被啟用時，對應的方法透過 execute 方法被呼叫。 於是這裡在互動中每個互動的參與者（本例中即按鈕）將自己的行為提交給中介者並且由中介者將這些行為轉給對應的參與者。 import javaawtFont import javaawteventActionEvent import javaawteventActionListener import javaxswingJButton import javaxswingJFrame import javaxswingJLabel import javaxswingJPanel Colleague interface interface Command void execute Abstract Mediator interface Mediator void book void view void search void registerView BtnView v void registerSearch BtnSearch s void registerBook BtnBook b void registerDisplay LblDisplay d Concrete mediator class ParticipantMediator implements Mediator BtnView btnView BtnSearch btnSearch BtnBook btnBook LblDisplay show public void registerView BtnView v btnView v public void registerSearch BtnSearch s btnSearch s public void registerBook BtnBook b btnBook b public void registerDisplay LblDisplay d show d public void book btnBooksetEnabled false btnViewsetEnabled true btnSearchsetEnabled true showsetText booking public void view btnViewsetEnabled false btnSearchsetEnabled true btnBooksetEnabled true showsetText viewing public void search btnSearchsetEnabled false btnViewsetEnabled true btnBooksetEnabled true showsetText searching A concrete colleague class BtnView extends JButton implements Command Mediator med BtnView ActionListener al Mediator m super View addActionListener al med m medregisterView this public void execute medview A concrete colleague class BtnSearch extends JButton implements Command Mediator med BtnSearch ActionListener al Mediator m super Search addActionListener al med m medregisterSearch this public void execute medsearch A concrete colleague class BtnBook extends JButton implements Command Mediator med BtnBook ActionListener al Mediator m super Book addActionListener al med m medregisterBook this public void execute medbook class LblDisplay extends JLabel Mediator med LblDisplay Mediator m super Just start med m medregisterDisplay this setFont new Font Arial FontBOLD 24 class MediatorDemo extends JFrame implements ActionListener Mediator med new ParticipantMediator MediatorDemo JPanel p new JPanel padd new BtnView this med padd new BtnBook this med padd new BtnSearch this med getContentPane add new LblDisplay med North getContentPane add p South setSize 400 200 setVisible true public void actionPerformed ActionEvent ae Command comd Command aegetSource comdexecute public static void main String args new MediatorDemo 另見 Data mediation 設計模式：可複用面向物件軟體的基礎，本書引起計算機科學界對設計模式的研究 設計模式 計算機，解決常見軟體設計問題的標準化方法 參考文獻 外部連結 Mediator Design Pattern Is the use of the mediator pattern recommend Stack Overflow Category 軟體設計模式 Category 有未審閱翻譯的頁面