第七篇 调整类间关系 第二十二章 - 中介者模式

  前文提到的“请求类”与“执行类”的角色定位是相对的。
  若 A 类中有方法调用 B 类,B 类中另有方法调用 A 类,A 类与 B 类就会相互依赖。此时每个类既是对方的请求类,又是对方的执行类。
  还有一些更复杂的情况,会使多个类循环依赖。
  看个例子。

// A
public class A {

  // 采集数据
  public static void data() {
    B.data();
    C.data();
  }

}

// B
public class B {

  // 采集数据
  public static void data() {
    A.data();
    C.data();
  }

}


// C
public class C {

  // 采集数据
  public static void data() {
    A.data();
    B.data();
  }

}

  A、B、C 中的每个类都需要依靠另外两个类采集数据,它们循环依赖,形成了一个“铁三角”。
  
  循环依赖是紧密的耦合关系,也是一种比较糟糕的情况,任何一方的修改都可能引起其他各方的被动调整。
  为使A、B、C相互解耦,我们不妨引入一个中间角色 M,让 A、B、C 只与 M 关联。由 M 居中协调,完成采集数据的工作。
  
  此时类间关系从“三角形”变成了“星形”。
  改造后的代码如下。

// A
public class A {

  // 采集数据
  public static void data() {
    M.data();
  }

}

// B
public class B {

  // 采集数据
  public static void data() {
    M.data();
  }

}

// C
public class C {

  // 采集数据
  public static void data() {
    M.data();
  }

}

// M
public class M {

  // 采集数据
  public static void data() {
    A.data();
    B.data();
    C.data();
  }

}

  A、B、C 把采集数据的工作委托给了 M,不再关心该工作的具体细节,它们被动调整的风险也将被 M 首先拦截。
  这种设计思路被称为中介者模式,M 即是中介者。
  再看个具体的例子,我们用中介者模式模拟某飞行指挥中心与各种飞行器的交互过程。

// 抽象飞行器
public abstract class Aircraft {

  private Center center;// 指挥中心

  // 与指挥中心建立联系(桥接模式)
  public Aircraft(Center obj) {
    this.center = obj;
    this.center.add(this);
  }

  // 上报数据
  public abstract void report();

  // 请求指令
  public void ask() {
    this.center.giveCommand();
  }

}

// 预警机
public class EarlyWarningAircraft extends Aircraft {

  public EarlyWarningAircraft(Center obj) {
    super(obj);
  }

  // 上报数据
  @Override
  public void report() {}

}

// 无人机
public class UnmannedAircraft extends Aircraft {

  public UnmannedAircraft(Center obj) {
    super(obj);
  }

  // 上报数据
  @Override
  public void report() {}

}

// 歼击机
public class FighterPlane extends Aircraft {

  public FighterPlane(Center obj) {
    super(obj);
  }

  // 上报数据
  @Override
  public void report() {}

}

// 抽象飞行指挥中心(中介者)
public abstract class Center {

  // 受控飞行器
  java.util.List<Aircraft> objs = new java.util.ArrayList<>();

  // 添加受控飞行器
  public boolean add(Aircraft obj) {
    return this.objs.add(obj);
  }

  // 采集数据
  public final void data() {
    for (Aircraft obj : this.objs) {
      obj.report();
    }
  }

  // 下达指令
  public abstract void giveCommand();

}

// 具体飞行指挥中心
public class CommandCenter extends Center {

  @Override
  public void giveCommand() {
    // 采集各方数据
    this.data();
    // 研判数据并下达指令
  }

}

// 测试类
public class Test {

  public void test() {
    // 飞行指挥中心
    Center center = new CommandCenter();
    // 各种飞行器
    Aircraft obj1 = new EarlyWarningAircraft(center);
    Aircraft obj2 = new UnmannedAircraft(center);
    Aircraft obj3 = new FighterPlane(center);
    // 飞行器请求指令,飞行指挥中心被动回应。
    obj1.ask();
    obj2.ask();
    obj3.ask();
    // 飞行指挥中心主动下达指令。
    center.giveCommand();
  }

}
posted on 2025-03-28 22:36  星辰河岳  阅读(39)  评论(0)    收藏  举报