一天一模式之8中介者模式

本文详细介绍了中介者模式,通过电脑配件交互的例子展示了没有主板时的复杂性,以及主板作为中介者如何简化交互。文章阐述了中介者模式的核心功能是封装对象之间的交互,减少类之间的耦合。同时,探讨了广义中介者模式在实际应用中的简化和变形,以及其优缺点,并提供了部门与人员关系的示例,进一步解释了如何在多对多关系中运用中介者模式。
摘要由CSDN通过智能技术生成

初识中介者模式

定义

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

结构和说明


- Mediator:
中介者接口。在里面定义各个同事之间交互需要的方法,可以是公共的通
讯方法,比如changed方法,大家都用,也可以是小范围的交互方法。
- ConcreteMediator:
具体中介者实现对象。它需要了解并维护各个同事对象,并负责具体的协
调各同事对象的交互关系。
- Colleague:
同事类的定义,通常实现成为抽象类,主要负责约束同事对象的类型,并
实现一些具体同事类之间的公共功能,比如:每个具体同事类都应该知道中介者
对象,也就是具体同事类都会持有中介者对象,就可以定义到这个类里面。
- ConcreteColleague:
具体的同事类,实现自己的业务,在需要与其它同事通讯的时候,就与持
有的中介者通信,中介者会负责与其它的同事交互。

示例代码

同事类的抽象父类

package cn.javass.dp.mediator.example1;
/**
 * 同事类的抽象父类
 */
public abstract class Colleague {
   
    /**
     * 持有中介者对象,每一个同事类都知道它的中介者对象
     */
    private Mediator mediator;
    /**
     * 构造方法,传入中介者对象
     * @param mediator 中介者对象
     */
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
    /**
     * 获取当前同事类对应的中介者对象
     * @return 对应的中介者对象
     */
    public Mediator getMediator() {
        return mediator;
    }
}

具体的同事类A

package cn.javass.dp.mediator.example1;
/**
 * 具体的同事类A
 */
public class ConcreteColleagueA extends Colleague {
   
    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }
    /**
     * 示意方法,执行某些业务功能
     */
    public void someOperation() {
        //在需要跟其他同事通信的时候,通知中介者对象
        getMediator().changed(this);
    }
}

具体的同事类B

package cn.javass.dp.mediator.example1;
/**
 * 具体的同事类B
 */
public class ConcreteColleagueB extends Colleague {
   
    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }
    /**
     * 示意方法,执行某些业务功能
     */
    public void someOperation() {
        //在需要跟其他同事通信的时候,通知中介者对象
        getMediator().changed(this);
    }
}


中介者,定义各个同事对象通信的接口

package cn.javass.dp.mediator.example1;
/**
 * 中介者,定义各个同事对象通信的接口
 */
public interface Mediator {
   
    /**
     * 同事对象在自身改变的时候来通知中介者的方法,
     * 让中介者去负责相应的与其他同事对象的交互
     * @param colleague 同事对象自身,好让中介者对象通过对象实例
     *                  去获取同事对象的状态
     */
    public void changed(Colleague colleague);
}

具体的中介者实现

package cn.javass.dp.mediator.example1;
/**
 * 具体的中介者实现
 */
public class ConcreteMediator implements Mediator {
   

    /**
     * 持有并维护同事A
     */
    private ConcreteColleagueA colleagueA;
    /**
     * 持有并维护同事B
     */
    private ConcreteColleagueB colleagueB;

    /**
     * 设置中介者需要了解并维护的同事A对象
     * @param colleague 同事A对象
     */
    public void setConcreteColleagueA(ConcreteColleagueA colleague) {
        colleagueA = colleague;
    }
    /**
     * 设置中介者需要了解并维护的同事B对象
     * @param colleague 同事B对象
     */
    public void setConcreteColleagueB(ConcreteColleagueB colleague) {
        colleagueB = colleague;
    }

    public void changed(Colleague colleague) {
        //某个同事类发生了变化,通常需要与其他同事交互
        //具体协调相应的同事对象来实现协作行为
    }

}

体会中介者模式

 如果没有主板

如果电脑里面没有了主板,那么各个配件之间就必须自行相互交互,以互
相传送数据,理论上说,基本上各个配件相互之间都存在交互数据的可能

有了主板,各个配件的交互完全通过主板来完成,每个配件都只需要和主
板交互,而主板知道如何和所有的配件打交道,那就简单多了

存在的问题

如果上面的情况发生在软件开发上呢?
如果把每个电脑配件都抽象成为一个类或者是子系统,那就相当于出现了
多个类之间相互交互,而且交互还很繁琐,导致每个类都必须知道所有需要交互
的类,也就是我们常说的类和类耦合了,是不是很麻烦?

这样一来,不但开发的时候每个类会复杂,因为要兼顾其它的类,更要命
的是每个类在发生改动的时候,需要通知所有相关的类一起修改,因为接口或者
是功能发生了变动,使用它的地方都得变,太可怕了吧!

那该如何来简化这种多个对象之间的交互呢?

使用电脑来看电影

为了演示,考虑一个稍微具体点的功能。在日常生活中,我们经常使用电
脑来看电影,把这个过程描述出来,这里仅仅考虑正常的情况,也就是有主板的
情况,简化后假定会有如下的交互过程:
- 1:首先是光驱要读取光盘上的数据,然后告诉主板,它的状态改变了
- 2:主板去得到光驱的数据,把这些数据交给CPU进行分析处理
- 3:CPU处理完后,把数据分成了视频数据和音频数据,通知主板,它处理完了
- 4:主板去得到CPU处理过后的数据,分别把数据交给显卡和声卡,去显示出视频和
发出声音

当然这是一个持续的、不断重复的过程,从而形成不间断的视频和声音,
具体的运行过程不在讨论之列,假设就有如上简单的交互关系就可以了。也就是
说想看电影,把光盘放入光驱,光驱开始读盘,就可以看电影了

使用模式的解决方案

示例代码

同事类的抽象父类
package cn.javass.dp.mediator.example2;

/**
 * 同事类的抽象父类
 */
public abstract class Colleague {
   
    /**
     * 持有中介者对象,每一个同事类都知道它的中介者对象
     */
    private Mediator mediator;
    /**
     * 构造方法,传
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值