定义
中介者模式(Mediator Pattern)又被称为调停者模式。它定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。它是一种对象行为型模式。
生活中最常见的例子就是租房中介是一种中介,如果我们想要租房可以通过中介和房东沟通,这时候其实并不需要知道对方是谁,也并不需要面对面,类似于电话、QQ、微信等等都是中介,能大大降低了沟通的复杂性。
组成部分
中介者模式总共有为以下三个组成部分:
1、抽象中介者(Mediator):抽象中介者是中介者的抽象类,它提供了同事对象注册与转发同事对象信息的抽象方法,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
2、中介者实现类(Concrete Mediator):即具体中介者。继承抽象中介者,并且实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。因为它管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
3、同事类(Colleague):如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。同事类也由两部分组成:抽象同事类(Abstract Colleague)和具体同事类(Concrete Colleague)。抽象同事类定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。具体同事类就是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
栗子
抽象中介者
public abstract class Mediator { public abstract void look(Colleague cl); public abstract void regist(Colleague cl); } 复制代码
抽象同事类:
public abstract class Colleague { protected Mediator mediator; public void setMedium(Mediator mediator) { this.mediator = mediator; } public abstract void get(); public abstract void send(); } 复制代码
具体中介类继承抽象中介类:
public class ConcreteMediator extends Mediator { //list同事管理对象 private List<Colleague> colleagues = new ArrayList<Colleague>(); @Override public void look(Colleague cl) { if (!colleagues.contains(cl)) { colleagues.add(cl); cl.setMedium(this); } } @Override public void regist(Colleague cl) { for (Colleague ob : colleagues) { if (!ob.equals(cl)) { ((Colleague) ob).get(); } } } } 复制代码
具体同事类继承抽象同事类:
public class ConcreteColleague1 extends Colleague{ @Override public void get() { System.out.println("具体同事类1收到请求。"); } @Override public void send() { System.out.println("具体同事类1发出请求。"); mediator.look(this); } } 复制代码
public class ConcreteColleague2 extends Colleague{ @Override public void get() { System.out.println("具体同事类2收到请求。"); } @Override public void send() { System.out.println("具体同事类2发出请求。"); mediator.look(this); } } 复制代码
测试方法:
public class MediatorPatternTest { public static void main(String[] args) { Mediator md = new ConcreteMediator(); Colleague c1, c2; c1 = new ConcreteColleague1(); c2 = new ConcreteColleague2(); md.look(c1); md.look(c2); c1.send(); c2.send(); } } 复制代码
运行结果如下:
通过上面代码可以发现中介者模式最为复杂的是同事类之间的关系,多个同事类之间相关关联,相互影响,如果是多个类(大于2个)它们之间的关系会是一种复杂的网状结构,这样它就是一种过度耦合的架构了,这样的系统肯定是不好的。这样的话就可以通过引入中介者,使得各个同事对象都只跟中介者打交道,这样过度耦合的网状结构就变成了扩散的星状结构了(可以自己脑补一下,就是以中介者对象为核心,同事类对象扩散开来),这是一个解耦的过程。可以把中介者理解为居委会大妈,不管社区有什么事情,都去找居委会大妈,她给你解决。
中介者模式的优点
1、使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
2、使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
3、使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
中介者模式的缺点
中介者模式的缺点很明显也比较少,比较显著的缺点就是:
1、具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂;
2、中介者模式是将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。使得系统难以维护。这样的话当同事类越来越多的时候,中介者就会越臃肿,变得复杂且难以维护。
应用场景
中介者模式的应用场景就是它的定义了。如果一个类同时依赖多个类的情况,那么适当的使用中介者模式可以使原本混乱的对象关系清晰,解耦关系。
比较常见的一个应用就是在MVC模式,其中的Controller控制器就是一个中介者对象。Model和View都是利用它进行通信。
总结
中介者模式是一种比较常用的模式,它的本质就是解耦多个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道。通过中介者对象统一管理这些交互关系。所以如果对象之间的关系并没有达到一种复杂的混乱关系,其实并没有必要使用中介者模式,只需要通过依赖关系管理即可,如果使用中介者模式不恰当会使得程序更加混乱。
本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star!