中介模式 (学习笔记2021.09.24)

中介模式 (学习笔记2021.09.24)

前言:

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

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

**主要解决:**对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。

**何时使用:**多个类相互耦合,形成了网状结构。

**如何解决:**将上述网状结构分离为星型结构。

**关键代码:**对象 Colleague 之间的通信封装到一个类中单独处理。

应用实例: 1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。 2、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。

**缺点:**中介者会庞大,变得复杂难以维护。

使用场景: 1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。 2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

**注意事项:**不应当在职责混乱的时候使用。

如果你对中介模式有所了解,你可能会知道,中介模式跟之前讲过的观察者模式有点相似,所以,今天我们还会详细讨论下这两种模式的区别。

中介模式的设计思想跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系(或者说依赖关系)从多对多(网状关系)转换为一对多(星状关系)。原来一个对象要跟 n 个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低了代码的复杂度,提高了代码的可读性和可维护性。

4wwHPA.md.png

前提条件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MbrPVcsb-1632453499924)(https://z3.ax1x.com/2021/09/23/4ws5h4.md.png)]

按照上图的条件与实现方式, 我们来使用中介者模式来实现需求

1.0 创建抽象中介

/**
 * 中介者抽象
 */
public interface Mediator {
  // 注册交互对象
  void register(Component obj);
  // components = 所有的需要通过中介来交互的对象, parameter = 交互方法参数
  void handleEvent(Class component, String parameter);
}

2.0 具体的实现中介操作行为

/**
 * @Author: ZhiHao
 * @Date: 2021/9/23 17:39
 * @Description: 中介者具体实现, 转发各种组件请求
 * @Versions 1.0
 **/
public class MediatorImpl implements Mediator {

    private final List<Component> componentList = new ArrayList<>(2);

    @Override
    public void register(Component obj) {
        componentList.add(obj);
    }

    @Override
    public void handleEvent(Class component, String parameter) {
        componentList.stream()
                .filter(component::isInstance)
                .findAny()
                .ifPresent(obj -> {
                    if (obj instanceof Alarm) {
                        System.out.println("MediatorImpl + Alarm");
                        ((Alarm) obj).onEvent(parameter);
                    }
                    if (obj instanceof Calendar) {
                        System.out.println("MediatorImpl + Calendar");
                        ((Calendar) obj).onEvent(parameter);
                    }
                });
    }
}

3.0 交互对象抽象类

/**
 * @Author: ZhiHao
 * @Date: 2021/9/23 17:31
 * @Description: 需要通过中介者交互的实现该接口
 * @Versions 1.0
 **/
public interface Component {
}

4.0 具体交互对象

/**
 * @Author: ZhiHao
 * @Date: 2021/9/23 17:44
 * @Description: 日历
 * @Versions 1.0
 **/
public class Calendar implements Component {

    public void onEvent(String msg){
        System.out.println("Calendar执行了"+msg);
    }
}
// *--------------------------------------------------
/**
 * @Author: ZhiHao
 * @Date: 2021/9/23 17:40
 * @Description: 闹钟
 * @Versions 1.0
 **/
public class Alarm implements Component {

    public void onEvent(String msg){
        System.out.println("Alarm执行了"+msg);
    }
}

进行测试

public void applicationTest() throws Exception {
    	 // 交互类
        Component alarm = new Alarm();
        Component calendar = new Calendar();
        // 中介者
        Mediator mediator = new MediatorImpl();
        // 注册到中介者, 让中介者知道所有的需要交互的对象
        mediator.register(alarm);
        mediator.register(calendar);
        // 然后需要调用, 通过中介调用, Alarm与Calendar进行了解耦
        // 调用闹钟 -- 甚至可以判断交互类的状态, 来改变调用顺序
        mediator.handleEvent(Alarm.class,"gg");
        // 调用日历
        mediator.handleEvent(Calendar.class,"eee");
    }
// -----------------------------------------------------
Alarm执行了gg
Calendar执行了eee

从代码中我们可以看出,原本业务逻辑会分散在各个控件中,现在都集中到了中介类中。实际上,这样做既有好处,也有坏处。好处是简化了控件之间的交互,坏处是中介类有可能会变成大而复杂的“上帝类”(God Class)。所以,在使用中介模式的时候,我们要根据实际的情况,平衡对象之间交互的复杂度和中介类本身的复杂度。

中介模式和观察者模式的区别在哪里呢?什么时候选择使用中介模式?什么时候选择使用观察者模式呢?

在观察者模式中,尽管一个参与者既可以是观察者,同时也可以是被观察者,但是,大部分情况下,交互关系往往都是单向的,一个参与者要么是观察者,要么是被观察者,不会兼具两种身份。也就是说,在观察者模式的应用场景中,参与者之间的交互关系比较有条理。

而中介模式正好相反。只有当参与者之间的交互关系错综复杂,维护成本很高的时候,我们才考虑使用中介模式。毕竟,中介模式的应用会带来一定的副作用,前面也讲到,它有可能会产生大而复杂的上帝类。除此之外,如果一个参与者状态的改变,其他参与者执行的操作有一定先后顺序的要求,这个时候,中介模式就可以利用中介类,通过先后调用不同参与者的方法,来实现顺序的控制,而观察者模式是无法实现这样的顺序要求的。

1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

懵懵懂懂程序员

如果节省了你的时间, 请鼓励

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

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

打赏作者

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

抵扣说明:

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

余额充值