前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >中介者模式浅析

中介者模式浅析

作者头像
孟君
发布2020-06-15 16:45:59
7600
发布2020-06-15 16:45:59
举报
文章被收录于专栏:孟君的编程札记

对于“中介”这个角色,大家在现实生活中也不陌生,比如房产中介。试想一下,如果没有中介这个角色,租房者和房东的关系直接的联系将呈现为网状结构,租房者和房东的关系将是多对多的关系,关系很复杂。当有房产中介的时候,租房者和房东之间将不用在一一的去交互,大家都只要和房产中介这一角色进行交互即可,由中介对象来管理对象的关联关系,避免相互交互的对象之间的紧耦合引用关系。这样,网状结构关系就简化为星型结构关系。如:

同样,在现实生活中的机场飞机起飞和降落,也都是和机场塔台交互,而不是飞机之间的进行交互的。如:

这种用一个中介对象(或者调停者)来封装一系列的对象交互的场景,就是今天要讲的中介者模式所使用的。

一. 中介者模式的基本介绍

意图

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

结构

中介者模式的基本结构如下:

这里涉及到的参与者有如下几种:

  • Mediator(中介者)
    • 中介者定义一个接口用于各同事(Colleague)对象通信。
  • ConcreteMediator(具体中介者)
    • 具体中介者通过协调各同事对象实现协作行为。
    • 了解并维护它的各个同事
  • Colleague(同事类)
    • 每一个同事类都知道它的中介者对象。
    • 每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。

参与者如何协作?

同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现写作行为。

二. 中介者模式的示例

接下来以一个模拟聊天室的简易代码来说明下中介者模式:

  • 抽象同事类

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.mediator;

public abstract class Participant {

  protected String name;

  public abstract void send(String message);

  public abstract void receive(String message, String sender);

  /**
   * @return the name
   */
  public String getName() {
    return name;
  }

  /**
   * @param name the name to set
   */
  public void setName(String name) {
    this.name = name;
  }


}
代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.mediator;

public class User extends Participant {

  private Mediator mediator = new ChatRoomMediator();

  public User(String name, Mediator mediator) {
    super();
    this.name = name;
    this.mediator = mediator;
    mediator.addParticipant(this);
  }

  @Override
  public void send(String message) {
    System.out.println(String.format("[%s]发送一条消息 :[%s]", this.getName(),message));
    mediator.sendMessage(message, this);
  }

  @Override
  public void receive(String message, String sender) {
    System.out.println(String.format("[%s]收到一条来自[%s]发送的消息 [%s]", this.getName(),sender,message));
  }

}


代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.mediator;

public interface Mediator {

  void sendMessage(String message, Participant participant);

  void addParticipant(Participant participant);

}
代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.mediator;

import java.util.ArrayList;
import java.util.List;

public class ChatRoomMediator implements Mediator{

  private List<Participant> participants = new ArrayList<Participant>();

  @Override
  public void sendMessage(String message, Participant participant) {
    for(Participant p : participants){
      if(p != participant){
        p.receive(message,participant.getName() );
      }
    }
  }

  @Override
  public void addParticipant(Participant participant) {
    participants.add(participant);
  }
}

测试一下:

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.mediator;

public class Main {

  public static void main(String[] args) {
    Mediator chatRoom = new ChatRoomMediator();
    User eric = new User("Eric",chatRoom);
    User lucy = new User("Lucy",chatRoom);
    User lilei  = new User("LiLei",chatRoom);
    User xiaoming  = new User("XiaoMing",chatRoom);

    eric.send("周末一起聚聚啊~~~");
    System.out.println();

    xiaoming.send("好啊");
    System.out.println();

    lilei.send("可以啊");
    System.out.println();

    lucy.send("好啊好啊,啤酒烤串搞起来");
  }
}

输出结果:

代码语言:javascript
复制
[Eric]发送一条消息 :[周末一起聚聚啊~~~]
[Lucy]收到一条来自[Eric]发送的消息 [周末一起聚聚啊~~~]
[LiLei]收到一条来自[Eric]发送的消息 [周末一起聚聚啊~~~]
[XiaoMing]收到一条来自[Eric]发送的消息 [周末一起聚聚啊~~~]

[XiaoMing]发送一条消息 :[好啊]
[Eric]收到一条来自[XiaoMing]发送的消息 [好啊]
[Lucy]收到一条来自[XiaoMing]发送的消息 [好啊]
[LiLei]收到一条来自[XiaoMing]发送的消息 [好啊]

[LiLei]发送一条消息 :[可以啊]
[Eric]收到一条来自[LiLei]发送的消息 [可以啊]
[Lucy]收到一条来自[LiLei]发送的消息 [可以啊]
[XiaoMing]收到一条来自[LiLei]发送的消息 [可以啊]

[Lucy]发送一条消息 :[好啊好啊,啤酒烤串搞起来]
[Eric]收到一条来自[Lucy]发送的消息 [好啊好啊,啤酒烤串搞起来]
[LiLei]收到一条来自[Lucy]发送的消息 [好啊好啊,啤酒烤串搞起来]
[XiaoMing]收到一条来自[Lucy]发送的消息 [好啊好啊,啤酒烤串搞起来]

三. 小结

中介者模式的优缺点:

优点:

(1):减少子类生成。Mediator将原本分布在多个对象间的行为集中在一起。改变这些行为只需生成Mediator的子类即可。这样各个Colleague类可被重用。

(2):它将各个Colleague解耦。Mediator有利于各Colleague间的松耦合,你可以独立的改变和复用各个Colleague类和Mediator类。

(3):中介者模式将多对多的相互作用转化为一对多的相互作用,使得对象之间的关系更加易于维护和理解。

(4):中介者模式将对象的行为和协作抽象化,将中介作为一个独立的概念并将其封装在一个对象中,使你的注意力从对象各自本身的行为转移到它们之间的交互上来。这有助于弄清楚一个系统中的对象是如何交互的。

缺点:

(1):调停者模式降低了同事对象的复杂性,代价是增加了中介者类的复杂性。这可能使得中介者自身成为一个难以维护的庞然大物。

(2):中介者经常充满了各个具体同事类的关系协调代码,这种代码常常是不能复用的。因此,具体同事类的复用是以中介者类的不可复用为代价的。

中介者模式 vs. 门面模式

门面模式和中介者模式很相似,两者均用来给出一个低耦合的系统。门面模式为一个子系统提供一个简单的接口,其中消息的传递是单方向的,因为门面模式的客户端只需要通过门面向子系统发出消息,而不是相反的情况。

中介者模式则不同,它与同事对象的相互作用是多方向的。

中介者模式 vs. 观察者模式

中介者(Mediator)强调的是同事(Colleague)类之间的交互而观察者(Observer)中的目标类(Subject)强调是目标改变后对观察者进行统一的通讯。

观察者模式需要观察者对象和主题对象的相互协作才能达到目的,而且一个观察主题对象通常有几个观察者对象,而一个观察者对象也可以同时观察几个主题对象。

Colleague可以使用观察者模式与Mediator进行交互。

参考

[1]. 阎宏. Java与模式.电子工业出版社

[2]. Erich Gamma. 设计模式-可复用面向对象软件的基础. 机械工业出版社.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孟君的编程札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 中介者模式的基本介绍
  • 二. 中介者模式的示例
  • 三. 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档