目录
- 1.概述
- 2.结构
- 3.案例实现
- 3.1.抽象中介类
- 3.2.抽象同事类
- 3.3.具体同事类
- 3.4.具体中介类
- 3.5.测试
- 4.优缺点
- 5.使用场景
1.概述
(1)一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下左图中,有 6 个同事类对象,假如对象 1 发生变化,那么将会有 4 个对象受到影响。如果对象 2 发生变化,那么将会有 5 个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
(2)如果引入中介者模式,那么同事类之间的关系将变为星型结构,从下右图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
(3)中介者模式 (Mediator Pattern) 是一种行为型设计模式,它允许对象通过一个中介对象来进行协作,而不是直接相互引用,从而降低对象之间的耦合度,同时提高代码的可维护性和可扩展性。
2.结构
中介者模式包含以下主要角色:
- 抽象中介者 (Mediator) 角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者 (Concrete Mediator) 角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类 (Colleague) 角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类 (Concrete Colleague) 角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
3.案例实现
【例】租房:现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。其类图下:
具体实现代码如下:
3.1.抽象中介类
Mediator.java
//抽象中介者类
public abstract class Mediator {public abstract void constact(String message, Person person);
}
3.2.抽象同事类
Person.java
//抽象同事类
public abstract class Person {protected String name;protected Mediator mediator;public Person(String name, Mediator mediator) {this.name = name;this.mediator = mediator;}
}
3.3.具体同事类
//租房者
public class Tenant extends Person{public Tenant(String name, Mediator mediator) {super(name, mediator);}//和中介沟通的方法public void constact(String message){mediator.constact(message, this);}//获取信息public void getMessage(String message){System.out.println("租房者" + name + "获取到的信息是:" + message);}
}
HouseOwner.java
//房主类
public class HouseOwner extends Person{public HouseOwner(String name, Mediator mediator) {super(name, mediator);}//和中介沟通的方法public void constact(String message){mediator.constact(message,this);}//获取信息public void getMessage(String message){System.out.println("房主" + name + "获取到的信息是:" + message);}
}
3.4.具体中介类
MediatorStructure.java
//具体的中介者角色类
public class MediatorStructure extends Mediator {//聚合房主和具体的租房者对象private HouseOwner houseOwner;private Tenant tenant;public HouseOwner getHouseOwner() {return houseOwner;}public void setHouseOwner(HouseOwner houseOwner) {this.houseOwner = houseOwner;}public Tenant getTenant() {return tenant;}public void setTenant(Tenant tenant) {this.tenant = tenant;}@Overridepublic void constact(String message, Person person) {if (person == houseOwner) {tenant.getMessage(message);} else {houseOwner.getMessage(message);}}
}
3.5.测试
Client.java
public class Client {public static void main(String[] args) {//创建中介者对象MediatorStructure mediator = new MediatorStructure();//创建租房者对象Tenant tenant = new Tenant("李四", mediator);//创建房主对象HouseOwner houseOwner = new HouseOwner("张三", mediator);//中介者要知道具体的房主和租房者mediator.setTenant(tenant);mediator.setHouseOwner(houseOwner);tenant.constact("我要租三室的房子!");houseOwner.constact("我这里有三室的房子,你要租吗?");}
}
输出结果如下:
房主张三获取到的信息是:我要租三室的房子!
租房者李四获取到的信息是:我这里有三室的房子,你要租吗?
4.优缺点
(1)中介者模式的优点包括:
- 减少对象之间的直接耦合:通过引入中介者对象,各个对象不再直接相互引用,而是通过中介者来协调和管理交互,从而降低了对象之间的依赖程度。
- 简化对象的交互逻辑:中介者模式将对象之间的交互行为集中在中介者对象中实现,各个对象只需要与中介者进行通信,不需要了解其他对象的具体细节,从而简化了对象之间的交互逻辑。
- 提高系统的可维护性和可扩展性:通过降低对象之间的耦合度,中介者模式使系统更加灵活和易于维护。当系统需要新增一些交互行为时,只需要修改中介者对象即可,无需修改各个同事对象。
- 促进代码重用:中介者模式可以将对象之间公共的交互行为抽象到中介者对象中,从而可以更好地复用代码。
(2)中介者模式的缺点包括:
- 中介者对象可能会变得复杂:随着系统中的对象和交互行为增多,中介者对象可能会承担过多的责任,变得复杂和庞大。
- 中介者模式可能导致性能问题:因为所有的交互行为都通过中介者进行,所以中介者可能成为系统的瓶颈,导致性能问题。
- 增加了系统的复杂性:中介者模式增加了一个新的抽象层次,引入了中介者对象,使系统的架构更加复杂,对于简单的交互行为并不适用。
(3)所以在使用中介者模式时,需要权衡其优势和缺点,并根据具体情况进行选择。它适用于对象之间的交互关系复杂、需要集中管理和协调的场景,但对于简单的交互行为,可能会过于繁琐和不必要。
5.使用场景
(1)中介者模式适用于以下场景:
- 对象之间的交互关系复杂:当系统中的对象之间存在复杂的交互关系,很难直接进行管理和协调时,可以引入中介者模式来简化和集中管理对象之间的交互行为。
- 需要减少对象之间的耦合度:当对象之间的直接引用和依赖关系较多,难以维护和扩展时,可以使用中介者模式来解耦对象之间的关系,通过统一的中介者来进行交互。
- 多个对象共享一些公共行为或信息:当多个对象需要共享某些公共行为或信息,并且希望集中管理和协调这些行为或信息时,可以使用中介者模式。
- 多个对象之间的交互频繁:当多个对象之间频繁进行交互,且存在复杂的交互逻辑时,可以使用中介者模式来简化交互过程,提高代码的可维护性和可扩展性。
(2)一些常见的应用中介者模式的场景包括:
- 图形界面中的 MVC 模式:在 MVC 模式中,中介者模式用于协调视图、模型和控制器之间的交互。
- 多人在线游戏系统:在多人在线游戏中,中介者模式可以用于处理玩家之间的交互、通信和协作。
- 航空管制系统:在航空管制系统中,中介者模式可以用于协调不同飞机之间的通信、路径规划和冲突解决。
- UI 组件库:在构建 UI 组件库或框架时,中介者模式可以用于统一管理组件之间的交互行为,从而提供统一的接口和规范。
(3)总之,中介者模式适用于需要集中管理和协调对象之间交互关系的复杂场景,以提高系统的灵活性、可维护性和可扩展性。