中介者模式

定义

中介者模式(Mediator Pattern)定义:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其松耦合,而且可以独立地改变它们之间的交互

核心思想

如果一个系统中对象之间的联系呈现出网状结构,对象之间存在大量多对多关系,将导致关系及其复杂,这些对象称为 "同事对象"。我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将同事对象之间的关系行为进行分离和封装,使之成为一个松耦合的系统。

角色

  • Mediator: 抽象中介者
  • ConcreteMediator: 具体中介者
  • Colleague: 抽象同事类
  • ConcreteColleague: 具体同事类

UML 图

普通箭头表示关联,实线的三角箭头表示继承。

本质

解耦各个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道。通过中介者对象统一管理这些交互关系,并且还可以在同事对象的逻辑上封装自己的逻辑。

代码演示

抽象同事类

  public interface Department {
      // 做本部门的事情
      void selfAction(); 
      // 向总经理发出申请
      void outAction();  
  }

具体同事类

  public class Finacial implements Department {
      // 持有中介者(总经理)的引用
      private Mediator m;  
      
      public Finacial(Mediator m) {
          super();
          this.m = m;
          m.register("finacial", this);
      }
  
      @Override
      public void outAction() {
          System.out.println("汇报工作!没钱了");
      }
  
      @Override
      public void selfAction() {
          System.out.println("管理财务");
      }
  
  }

具体同事类

  public class Market implements Department {
      // 持有中介者(总经理)的引用
      private Mediator m;  
      
      public Market(Mediator m) {
          super();
          this.m = m;
          m.register("market", this);
      }
  
      @Override
      public void outAction() {
          System.out.println("汇报项目承接的进度,需要资金支持");
          // 通过中介者调用同事类,并没有和同事类耦合。
          m.command("finacial");
      }
  
      @Override
      public void selfAction() {
          System.out.println("谈项目");
      }
  
  }

抽象中介者

  public interface Mediator {
      
      void register(String dname,Department d);
      
      void command(String dname);
      
  }

具体中介者

  public class President implements Mediator {
      
      private Map<String,Department> map = new HashMap<String , Department>();
      
      @Override
      public void command(String dname) {
          // 在不改变同事类的情况下,封装一些公共的逻辑
          System.out.println("执行前-----打印日志信息");
          map.get(dname).selfAction();
          System.out.println("执行后-----打印日志信息");
      }
  
      @Override
      public void register(String dname, Department d) {
          map.put(dname, d);
      }
  
  }

测试类

  public class Client {
      public static void main(String[] args) {
          Mediator m = new President();
          
          Market market = new Market(m);
          Finacial f = new Finacial(m);
          
          market.selfAction();
          market.outAction();    
      }
  }

开发中常见的场景

  • MVC,控制器(C) 就是一个中介者对象。M 和 V 都和他打交道。
  • 图形界面开发 GUI 中,多个组件之间的交互,可以将它们之间的引用和控制关系交由中介者负责,整体的窗口对象或者 DOM 对象就是这个中介者。
  • Java.lang.reflect.Method#invoke() 这个场景的分析将在评论区解答,大家看完文章后可以用这个为实例进行分析一波,欢迎在评论区讨论。

适用场景

  • 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象。

总结

中介者模式其实就是将一个复杂的事分离出来统一管理,对于复杂的系统来说,统一管理是有很大的好处的,比如:现在流行 SSM,为什么使用 spring 这个容器来管理对象之间的关系和生命周期呢?很明显通过 spring 管理对象使得我们开发变简单了,项目的耦合度也低了。spring 就可以看成一个中介者,当我们需要哪个对象时向它要就完事了,至于对象的关系、生命周期 spring 会帮我们管理。如果不使用 spring,当一个系统越来越大,对象有成千个关系各种多对多,让程序猿自己去管理对象之间的关系,那我估计程序猿的发量又该少点了。希望大家好好品味一下这句话:将同事对象之间的关系行为进行分离和封装。

原文发布于微信公众号 - Java知其所以然(gh_37a1335e2608)

原文发表时间:2019-01-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券