在我们的生活中处处充斥着“中介者”,比如你租房、买房、出国留学、找工作、旅游等等可能都需要那些中介者的帮助,同时我们也深受其害,高昂的中介费,虚假信息。软件中也同样如此,对象与对象之间存在着很强、复杂的关联关系,如果没有类似“中介者”会很容易出问题的,譬如:
1、 对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
2、 对象之间的连接增加会导致对象可复用性降低。
3、 系统的可扩展性低。增加一个新的对象,我们需要在其相关连的对象上面加上引用,这样就会导致系统的耦合性增高,使系统的灵活性和可扩展都降低。
在前面我就知道如果两个类不必彼此通信,那么这两个类就不应当发生直接关联的关系。如果其中一个类需要调用另一个类中的方法,我们可以通过第三方来转发这个调用。所以对于关系比较复杂的系统,我们为了减少对象之间的关联关系,使之成为一个松耦合系统,我们就需要使用中介者模式。
通过中介者模式,我们可以将复杂关系的网状结构变成结构简单的以中介者为核心的星形结构,每个对象不再和它与之关联的对象直接发生相互作用,而是通过中介者对象来另一个对象发生相互作用。
模式定义所谓中介者模式就是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
比如MVC 模式,C(Controller 控制器)是M(Model 模型)和V(View 视图)的中介者,在前后端交互时起到了中间人的作用
通过定义我们可以看出中介者主要是通过中介对象来封装对象之间的关系,使之各个对象在不需要知道其他对象的具体信息情况下通过中介者对象来与之通信。同时通过引用中介者对象来减少系统对象之间关系,提高了对象的可复用和系统的可扩展性。
但是就是因为中介者对象封装了对象之间的关联关系,导致中介者对象变得比较庞大,所承担的责任也比较多。它需要知道每个对象和他们之间的交互细节,如果它出问题,将会导致整个系统都会出问题。所以它比较容易应用也很容易误用。故当系统中出现了“多对多”交互复杂的关系群时,千万别急着使用中介者模式,你首先需要做的就是反思你的系统在设计上是不是合理。
模式结构 下图是中介者模式的UML结构图:
它主要包含如下几个角色:
Mediator: 抽象中介者。定义了同事对象到中介者对象之间的接口。
ConcreteMediator: 具体中介者。实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。
Colleague: 抽象同事类。
ConcreteColleague: 具体同事类。每个具体同事类都只需要知道自己的行为即可,但是他们都需要认识中介者。
在中介者模式中中介者对象处于核心地位,因为它定义了整个系统中所有具体同事类之间的关系。在整个系统中它主要承担两个方面的责任。
1、 结构上起到中转作用。通过中介者对象对关系的封装,使得具体的同事类不再需要显示的引用其他对象,它只需要通过中介者就可以完成与其他同事类之间的通信。
2、 行为上起到协作作用。中介者对同事类之间的关系进行封装,同事类在不需要知道其他对象的情况下通过中介者与其他对象完成通信。在这个过程中同事类是不需要指明中介者该如何做,中介者可以根据自身的逻辑来进行协调,对同事的请求进一步处理,将同事成员之间的关系行为进行分离和封装。
同时由于中介者对对象的关系进行了封装,使得各个同事类之间的耦合减少了,使得他们可以独立改变和复用。
都说男大当婚女大当嫁,古代有媒婆、红娘撮合婚事,现在有婚姻介绍所,它们都相当与中介者。在相亲者年龄还小的时候,它们想要自己去寻找真爱
package com.dongguo.mediator;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:29
* @description:
*/
public abstract class Person {
private String name;
private int condition;//家庭情况级别
public Person() {
}
public Person(String name, int condition) {
this.name = name;
this.condition = condition;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCondition() {
return condition;
}
public void setCondition(int condition) {
this.condition = condition;
}
public abstract void getPartner(Person person);
}
package com.dongguo.mediator;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:30
* @description:
*/
public class Man extends Person {
public Man(String name,int condition){
super(name,condition);
}
@Override
public void getPartner(Person person) {
if (person instanceof Man){
System.out.println("我不喜欢男的");
}else {
if (this.getCondition() == person.getCondition()){
System.out.println("门当户对");
}else {
System.out.println("不相配");
}
}
}
}
package com.dongguo.mediator;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:31
* @description:
*/
public class Woman extends Person{
public Woman(String name,int condition){
super(name,condition);
}
@Override
public void getPartner(Person person) {
if (person instanceof Woman){
System.out.println("我不喜欢女的");
}else {
if (this.getCondition() == person.getCondition()){
System.out.println("门当户对");
}else {
System.out.println("不相配");
}
}
}
}
package com.dongguo.mediator;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:31
* @description:
*/
public class Client {
public static void main(String[] args) {
Person man = new Man("张三",18);
Person woman = new Woman("李四",25);
man.getPartner(woman);
}
}
运行结果:
不相配
随着年龄越来越大,家里人催着赶紧找对象结婚,就不得不找到婚姻介绍所去相亲。
package com.dongguo.mediator;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:32
* @description: 中介者
*/
public class Mediator {
private Man man;
private Woman woman;
public void setMan(Man man) {
this.man = man;
}
public void setWoman(Woman woman) {
this.woman = woman;
}
public void getPartner(Person person){
//设置相亲对象
if (person instanceof Man){
this.setMan((Man) person);
}else {
this.setWoman((Woman) person);
}
if (man.getCondition() == woman.getCondition()){
System.out.println("门当户对");
}else {
System.out.println("我反对这门亲事");
}
}
}
package com.dongguo.mediator.improve;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:34
* @description:
*/
public abstract class Person {
private String name;
private int condition;
private Mediator mediator;
public Person() {
}
public Person(String name, int condition, Mediator mediator) {
this.name = name;
this.condition = condition;
this.mediator = mediator;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCondition() {
return condition;
}
public void setCondition(int condition) {
this.condition = condition;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public abstract void getPartner(Person person);
}
package com.dongguo.mediator.improve;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:35
* @description:
*/
public class Man extends Person {
public Man(String name,int condition,Mediator mediator){
super(name,condition,mediator);
}
@Override
public void getPartner(Person person) {
this.getMediator().setMan(this);
this.getMediator().getPartner(person);
}
}
package com.dongguo.mediator.improve;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:35
* @description:
*/
public class Woman extends Person{
public Woman(String name,int condition,Mediator mediator){
super(name,condition,mediator);
}
@Override
public void getPartner(Person person) {
this.getMediator().setWoman(this);
this.getMediator().getPartner(person);
}
}
package com.dongguo.mediator.improve;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:31
* @description:
*/
public class Client {
public static void main(String[] args) {
Mediator mediator = new Mediator();
Person man = new Man("张三",30,mediator);
Person woman = new Woman("lisi",30,mediator);
man.getPartner(woman);
}
}
运行结果:
门当户对
优点
1、 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使系统成为松耦合系统。
2、 减少了子类的生成。
3、 可以减少各同事类的设计与实现。
缺点由于中介者对象封装了系统中对象之间的相互关系,导致其变得非常复杂,使得系统维护比较困难。
模式适用场景1、 系统中对象之间存在比较复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
2、 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
模式总结1、 在中介者模式中通过引用中介者对象,将系统中有关的对象所引用的其他对象数目减少到最少。它简化了系统的结构,将系统由负责的网状结构转变成简单的星形结构,中介者对象在这里起到中转和协调作用。
2、 中介者类是中介者模式的核心,它对整个系统进行控制和协调,简化了对象之间的交互,还可以对对象间的交互进行进一步的控制。
3、 通过使用中介者模式,具体的同事类可以独立变化,通过引用中介者可以简化同事类的设计和实现。
4、 就是由于中介者对象需要知道所有的具体同事类,封装具体同事类之间相互关系,导致中介者对象变得非常复杂,系统维护起来较为困难。