【设计模式】第二十二章:中介者模式详解及应用案例

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式



中介者模式

一、定义

摘自百度百科: 用一个中介对象来封装一系列对象的交互,从而把一批原来可能是交互关系复杂的对象转换成一组松散耦合的中间对象,以有利于维护和修改。


二、角色分类

抽象中介者(Mediator)

声明了同时对象到中介者对象的接口

具体中介者(Concrete Mediator)

其为具体中介者的子类,从具体的同事对象接收消息,向具体同事发出命令

抽象同事角色(Colleague)

声明了中介者对象接口,它只知道中介者对象,而不知道其他同事对象

具体同事角色(Concrete Colleague)

其为抽象同事的子类,每个具体同事类都知道自己在小范围内的行为,而不知道其在大范围内的目的

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

在这里插入图片描述

具体实现

抽象中介者(Mediator)

public abstract class Mediator {
  protected ConcreteColleagueA colleagueA;
  protected ConcreteColleagueB colleagueB;

  public void setColleagueA(ConcreteColleagueA colleague) {
    this.colleagueA = colleague;
  }

  public void setColleagueB(ConcreteColleagueB colleague) {
    this.colleagueB = colleague;
  }

  public abstract void transferA();

  public abstract void transferB();
}

具体中介者(Concrete Mediator)

public class ConcreteMediator extends Mediator {
  /**
   * 由具体同事A,向具体同事B发出指令
   */
  @Override
  public void transferA() {
    this.colleagueB.selfMethodB();
  }

  /**
   * 由具体同事B,向具体同事A发出指令
   */
  @Override
  public void transferB() {
    this.colleagueA.selfMethodA();
  }
}

抽象同事类(Colleague)

public abstract class Colleague {
  protected Mediator mediator;

  public Colleague(Mediator mediator) {
    this.mediator = mediator;
  }
}

具体同事类(Concrete Colleague)

public class ConcreteColleagueA extends Colleague {
  public ConcreteColleagueA(Mediator mediator) {
    super(mediator);
    this.mediator.setColleagfueA(this);
  }

  /**
   * 自有方法
   */
  public void selfMethodA() {
    System.out.println("同事A收到中介协作通知")
  }

  /**
   * 依赖方法
   */
  public void depMethodA() {
    System.out.println(this.getClass().getSimpleName()+ " depMethodA通知中介者进行转发协作")
  }
}
public class ConcreteColleagueB extends Colleague {
  public ConcreteColleagueB(Mediator mediator) {
    super(mediator);
    this.mediator.setColleageB(this);
  }

  /**
   * 自有方法
   */
  public void selfMethodB() {
    System.out.println("同事B收到中介协作通知");
  }

  /**
   * 依赖方法
   */
  public void depMethodB() {
    System.out.println(this.getClass().getSimpleName() + " depMethodB通知中介者进行转发协作");
    // 中介者进行转发协作
    this.mediator.transferB();
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    // 创建抽象中介者
    Mediator mediator = new ConcreteMediator();
    // 具体同事类
    ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
    ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
    // 中介者进行转发协作,A转发给B
    colleagueA.depMethodA();
    System.out.println("-------------------------");
    // 中介者进行转发协作,B转发给A
    colleagueB.depMethodB();
  }
}

运行结果

ConcreteColleagueA depMethodA通知中介者进行转发协作
同事B收到中介协作通知
-------------------------
ConcreteColleagueB depMethodB通知中介者进行转发协作
同事A收到中介协作通知

四、应用场景

以下部分内容摘自菜鸟教程

意图: 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

主要解决: 对于一些固定文法构建一个解释句子的解释器。

何时使用: 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

如何解决: 构建语法树,定义终结符与非终结符。

关键代码: 构建环境类,包含解释器之外的一些全局信息,一般是 HashMap。

应用实例: 编译器、运算表达式计算。

使用场景:

  1. 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
  2. 一些重复出现的问题可以用一种简单的语言来进行表达。
  3. 一个简单语法需要解释的场景。

注意事项: 可利用场景比较少,JAVA 中如果碰到可以用 expression4J 代替。


五、优缺点

优点

  1. 可扩展性比较好,灵活。
  2. 增加了新的解释表达式的方式。
  3. 易于实现简单文法。

缺点

  1. 可利用场景比较少。
  2. 对于复杂的文法比较难维护。
  3. 解释器模式会引起类膨胀。
  4. 解释器模式采用递归调用方法。

推荐

关注博客和公众号获取最新文章

Bummon’s BlogBummon’s Home公众号

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bummon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值