fbpx
维基百科

中介者模式

软件工程领域,中介者模式定义了一个中介者对象,该对象封装了系统中对象间的交互方式。 由于它可以在运行时改变程序的行为,这种模式是一种行为型模式

通常程序由大量的组成,这些类中包含程序的逻辑和运算。 然而,当开发者将更多的类加入到程序中之后,类间交互关系可能变得更为复杂,这会使得代码变得更加难以阅读和维护,尤其是在重构的时候。 此外,程序将会变得难以修改,因为对其所做的任何修改都有可能影响到其它几个类中的代码。

中介者模式中,对象间的通信过程被封装在一个中介者(调解人)对象之中。 对象之间不再直接交互,而是通过调解人进行交互。 这么做可以减少可交互对象间的依赖,从而降低耦合

概述

中介者模式[1]是23个周知模式( 即GoF设计模式)中的一个,GoF设计模式旨在提供重复出现的设计问题的解决方案,以编写灵活和可复用的面向对象软件。也就是说,使对象更加易于实现、修改、测试和复用。

中介者设计模式可以解决什么问题? [2]

  • 避免一组相互交互的对象之间出现紧耦合。
  • 能够独立地改变一组对象之间的交互关系而不影响其他对象。

使用直接逐个访问并更新彼此的方式进行对象间的交互灵活性低,因为这种方式使对象彼此间紧密耦合,导致不可能单独修改类间交互关系本身,而不影响关系中进行交互的类。并且这种方式会令对象变得无法复用,并且难以测试。

由于紧耦合的对象过多了解其他对象的内部细节,这种对象难以实现、修改、测试以及复用。

中介者模式如何解决上述问题?

  • 定义一个独立的中介者(调解员)的对象,封装一组对象之间的交互关系。
  • 对象将自己的交互委托给中介者执行,避免直接与其他对象进行交互。

对象利用中介者对象与其他对象进行间接交互,中介者对象负责控制和协调交互关系,这么做可使得对象间松耦合。这些对象只访问中介者,不了解其他对象的细节。

另见UML类图和时序图如下。

定义

中介者模式是为了“定义一个封装了对象间交互关系的对象”。这种方式避免了显式调用其他类,促进了类间的松耦合,并且使得类间交互关系本身可以单独修改[3]。客户类可以使用中介者向其他客户类发送信息,并且通过中介者引发的事件收到信息。

结构

UML类图和时序图

 
一个中介者模式典型实现的UML类图和时序图。 [4]

在以上 UML 类图中,类 Colleague1Colleague2 不引用和更新彼此。 相反,它们引用一个通用的 Mediator 接口以实现类间交互的控制和协调(通过mediate()),这使得它们独立于类间交互的具体细节。 类 Mediator1 实现了类 Colleague1Colleague2之间的交互细节。

上述 UML 时序图 显示了这些类之间在运行时的交互过程: 在这个例子中,一个 Mediator1 对象 中介,即控制和协调了 Colleague1Colleague2的对象之间的交互。

如果 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)  {  this.Component1.SetState(state);  this.Component2.SetState(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)  {  Console.WriteLine("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;  _mediator.MessageReceived += new MessageReceivedEventHandler(Receive);  }  private void Receive(string message, string from)  {  if (from != Name)  Console.WriteLine("{0} received '{1}' from {2}", Name, message, from);  }  public void Send(string message)  {  _mediator.Send(message, Name);  } } 

Java

在以下示例中,一个中介者对象控制了三个互相交互的按钮的状态,为此它有设置状态的三个方法:book(), view()search()。 当相应的按钮被激活时,对应的方法通过execute()方法被调用。

于是这里在交互中每个交互的参与者(本例中即按钮)将自己的行为提交给中介者并且由中介者将这些行为转给对应的参与者。

import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; //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() { btnBook.setEnabled(false); btnView.setEnabled(true); btnSearch.setEnabled(true); show.setText("booking..."); } public void view() { btnView.setEnabled(false); btnSearch.setEnabled(true); btnBook.setEnabled(true); show.setText("viewing..."); } public void search() { btnSearch.setEnabled(false); btnView.setEnabled(true); btnBook.setEnabled(true); show.setText("searching..."); } } //A concrete colleague class BtnView extends JButton implements Command { Mediator med; BtnView(ActionListener al, Mediator m) { super("View"); addActionListener(al); med = m; med.registerView(this); } public void execute() { med.view(); } } //A concrete colleague class BtnSearch extends JButton implements Command { Mediator med; BtnSearch(ActionListener al, Mediator m) { super("Search"); addActionListener(al); med = m; med.registerSearch(this); } public void execute() { med.search(); } } //A concrete colleague class BtnBook extends JButton implements Command { Mediator med; BtnBook(ActionListener al, Mediator m) { super("Book"); addActionListener(al); med = m; med.registerBook(this); } public void execute() { med.book(); } } class LblDisplay extends JLabel { Mediator med; LblDisplay(Mediator m) { super("Just start..."); med = m; med.registerDisplay(this); setFont(new Font("Arial", Font.BOLD, 24)); } } class MediatorDemo extends JFrame implements ActionListener { Mediator med = new ParticipantMediator(); MediatorDemo() { JPanel p = new JPanel(); p.add(new BtnView(this, med)); p.add(new BtnBook(this, med)); p.add(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) ae.getSource(); comd.execute(); } public static void main(String[] args) { new MediatorDemo(); } } 

另见

参考文献

  1. ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. 1994: 273ff. ISBN 0-201-63361-2. 
  2. ^ . w3sDesign.com. [2017-08-12]. (原始内容存档于2018-12-16). 
  3. ^ Gang Of Four
  4. ^ The Mediator design pattern - Structure and Collaboration. w3sDesign.com. [2017-08-12]. (原始内容于2018-12-16). 

外部链接

  • Is the use of the mediator pattern recommend? - Stack Overflow(页面存档备份,存于互联网档案馆

中介者模式, 在软件工程领域, 定义了一个中介者对象, 该对象封装了系统中对象间的交互方式, 由于它可以在运行时改变程序的行为, 这种模式是一种行为型模式, 通常程序由大量的类组成, 这些类中包含程序的逻辑和运算, 然而, 当开发者将更多的类加入到程序中之后, 类间交互关系可能变得更为复杂, 这会使得代码变得更加难以阅读和维护, 尤其是在重构的时候, 此外, 程序将会变得难以修改, 因为对其所做的任何修改都有可能影响到其它几个类中的代码, 在中, 对象间的通信过程被封装在一个中介者, 调解人, 对象之中, 对象之间. 在软件工程领域 中介者模式定义了一个中介者对象 该对象封装了系统中对象间的交互方式 由于它可以在运行时改变程序的行为 这种模式是一种行为型模式 通常程序由大量的类组成 这些类中包含程序的逻辑和运算 然而 当开发者将更多的类加入到程序中之后 类间交互关系可能变得更为复杂 这会使得代码变得更加难以阅读和维护 尤其是在重构的时候 此外 程序将会变得难以修改 因为对其所做的任何修改都有可能影响到其它几个类中的代码 在中介者模式中 对象间的通信过程被封装在一个中介者 调解人 对象之中 对象之间不再直接交互 而是通过调解人进行交互 这么做可以减少可交互对象间的依赖 从而降低耦合 目录 1 概述 2 定义 3 结构 3 1 UML类图和时序图 3 2 类图 4 范例 4 1 C 4 2 Java 5 另见 6 参考文献 7 外部链接概述 编辑中介者模式 1 是23个周知模式 即GoF设计模式 中的一个 GoF设计模式旨在提供重复出现的设计问题的解决方案 以编写灵活和可复用的面向对象软件 也就是说 使对象更加易于实现 修改 测试和复用 中介者设计模式可以解决什么问题 2 避免一组相互交互的对象之间出现紧耦合 能够独立地改变一组对象之间的交互关系而不影响其他对象 使用直接逐个访问并更新彼此的方式进行对象间的交互灵活性低 因为这种方式使对象彼此间紧密耦合 导致不可能单独修改类间交互关系本身 而不影响关系中进行交互的类 并且这种方式会令对象变得无法复用 并且难以测试 由于紧耦合的对象过多了解其他对象的内部细节 这种对象难以实现 修改 测试以及复用 中介者模式如何解决上述问题 定义一个独立的中介者 调解员 的对象 封装一组对象之间的交互关系 对象将自己的交互委托给中介者执行 避免直接与其他对象进行交互 对象利用中介者对象与其他对象进行间接交互 中介者对象负责控制和协调交互关系 这么做可使得对象间松耦合 这些对象只访问中介者 不了解其他对象的细节 另见UML类图和时序图如下 定义 编辑中介者模式是为了 定义一个封装了对象间交互关系的对象 这种方式避免了显式调用其他类 促进了类间的松耦合 并且使得类间交互关系本身可以单独修改 3 客户类可以使用中介者向其他客户类发送信息 并且通过中介者引发的事件收到信息 结构 编辑UML类图和时序图 编辑 一个中介者模式典型实现的UML类图和时序图 4 在以上 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 this Component1 SetState state this Component2 SetState 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 Console WriteLine 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 mediator MessageReceived new MessageReceivedEventHandler Receive private void Receive string message string from if from Name Console WriteLine 0 received 1 from 2 Name message from public void Send string message mediator Send message Name Java 编辑 在以下示例中 一个中介者对象控制了三个互相交互的按钮的状态 为此它有设置状态的三个方法 book view 和 search 当相应的按钮被激活时 对应的方法通过execute 方法被调用 于是这里在交互中每个交互的参与者 本例中即按钮 将自己的行为提交给中介者并且由中介者将这些行为转给对应的参与者 import java awt Font import java awt event ActionEvent import java awt event ActionListener import javax swing JButton import javax swing JFrame import javax swing JLabel import javax swing JPanel 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 btnBook setEnabled false btnView setEnabled true btnSearch setEnabled true show setText booking public void view btnView setEnabled false btnSearch setEnabled true btnBook setEnabled true show setText viewing public void search btnSearch setEnabled false btnView setEnabled true btnBook setEnabled true show setText searching A concrete colleague class BtnView extends JButton implements Command Mediator med BtnView ActionListener al Mediator m super View addActionListener al med m med registerView this public void execute med view A concrete colleague class BtnSearch extends JButton implements Command Mediator med BtnSearch ActionListener al Mediator m super Search addActionListener al med m med registerSearch this public void execute med search A concrete colleague class BtnBook extends JButton implements Command Mediator med BtnBook ActionListener al Mediator m super Book addActionListener al med m med registerBook this public void execute med book class LblDisplay extends JLabel Mediator med LblDisplay Mediator m super Just start med m med registerDisplay this setFont new Font Arial Font BOLD 24 class MediatorDemo extends JFrame implements ActionListener Mediator med new ParticipantMediator MediatorDemo JPanel p new JPanel p add new BtnView this med p add new BtnBook this med p add 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 ae getSource comd execute public static void main String args new MediatorDemo 另见 编辑Data mediation 设计模式 可复用面向对象软件的基础 本书引起计算机科学界对设计模式的研究 设计模式 计算机 解决常见软件设计问题的标准化方法参考文献 编辑 Erich Gamma Richard Helm Ralph Johnson John Vlissides Design Patterns Elements of Reusable Object Oriented Software Addison Wesley 1994 273ff ISBN 0 201 63361 2 The Mediator design pattern Problem Solution and Applicability w3sDesign com 2017 08 12 原始内容存档于2018 12 16 Gang Of Four The Mediator design pattern Structure and Collaboration w3sDesign com 2017 08 12 原始内容存档于2018 12 16 外部链接 编辑Mediator Design Pattern Is the use of the mediator pattern recommend Stack Overflow 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title 中介者模式 amp oldid 71785020, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。