概念:
中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来解耦多个相关对象之间的交互。中介者充当了多个对象之间的协调者,使得这些对象不需要直接相互通信,而是通过与中介者进行通信。中介者模式用于将一组相关对象的复杂交互逻辑封装到一个单独的类(即中介者)中。该类负责协调和管理这些对象之间的通信,并提供统一的接口供其他对象使用。
特点:
- 解耦关联对象:通过引入一个中介者来减少各个相关对象之间的直接依赖关系。
- 集中控制逻辑:将复杂的交互逻辑集中在一个类(即中介者)中管理和处理。
- 促进可扩展性:新添加或修改现有相关对象时,只需修改或扩展具体实现类而无需改变其他部分。
优点:
- 减少了多对多关系:将原本复杂且混乱的多对多关系转化为简单明确、清晰易懂且易维护的一对多关系。
- 提高了系统灵活性:由于各个同事类只依赖于抽象 Mediator 类,因此可以在不修改同事类的情况下增加新的中介者。
- 降低了对象之间的耦合性:各个同事类只需要知道中介者对象,而无需了解其他同事类的具体细节。
缺点:
- 中介者模式会导致中介者本身变得复杂,因为它需要处理多个相关对象之间的交互逻辑。
- 当系统中出现太多相关对象时,可能会导致中介者过于庞大和复杂。
适用场景:
- 系统内部各个对象之间存在复杂且紧密耦合的关系。
- 一个行为会影响其他相关对象,并且希望减少这些相互依赖关系。
- 需要集中控制一组相关对象之间的交互逻辑。
实现方式:
基于接口实现
实现原理:
定义一个抽象 Mediator 接口来约束具体 Mediator 类,并在其中声明各种协调方法。然后创建具体 Mediator 类来实现该接口,并在其中管理和协调相关对象之间的通信与交互逻辑。
实现代码:
mport java.util.ArrayList;
import java.util.List;// 中介者接口
interface Mediator {void sendMessage(String message, Colleague colleague);void addColleague(Colleague colleague);
}// 具体中介者类
class ConcreteMediator implements Mediator {private List<Colleague> colleagues;public ConcreteMediator() {this.colleagues = new ArrayList<>();}public void addColleague(Colleague colleague) {colleagues.add(colleague);}@Overridepublic void sendMessage(String message, Colleague colleague) {// 将消息广播给其他同事对象(除了发送方自身)for (Colleague c : colleagues) {if (c != colleague) {c.receiveMessage(message);}}}
}// 同事类接口
interface Colleague {void receiveMessage(String message);void sendMessage(String message);
}// 具体同事类A
class ConcreteColleagueA implements Colleague {private Mediator mediator;public ConcreteColleagueA(Mediator mediator){this.mediator=mediator;mediator.addColleague(this);}@Overridepublic void receiveMessage(String message) {System.out.println("ConcreteColleage A received: " + message);}@Overridepublic void sendMessage(String message) {System.out.println("ConcreteColleage A sent: " +message );mediator.sendMessage(message, this);}
}// 具体同事类B
class ConcreteColleagueB implements Colleague {private Mediator mediator;public ConcreteColleagueB(Mediator mediator){this.mediator=mediator;mediator.addColleague(this);}@Overridepublic void receiveMessage(String message) {System.out.println("ConcreteColleage B received: " +message );}@Overridepublic void sendMessage(String message) {System.out.println("ConcreteColleage B sent: " + message);mediator.sendMessage(message, this);}
}public class Main {public static void main(String[] args) {ConcreteMediator mediator = new ConcreteMediator();Colleague colleagueA = new ConcreteColleagueA(mediator);Colleague colleagueB = new ConcreteColleagueB(mediator);colleagueA.sendMessage("Hello, how are you?");colleagueB.sendMessage("I'm fine, thank you!");}
}
在上述示例中,我们定义了一个中介者接口 Mediator 和具体实现类 ConcreteMediator。然后创建了两个同事类 ConcreteColleague A和 ConcreteColleague B,并在其构造函数中将中介者对象传递进去。当同事对象需要发送消息时,会通过中介者进行广播并通知其他相关对象。
基于事件机制
基于事件机制的中介者模式是指通过使用观察者模式作为基础,将中介者类作为发布器(Publisher),其他相关对象作为订阅器(Subscriber)来实现。当某个对象发生变化时,通过中介者发布对应的事件通知其他相关对象进行相应操作。
实现原理:
- 定义一个抽象的中介者接口,其中包含注册、解注册和广播事件等方法。
- 创建具体的中介者类并实现抽象接口,在其中维护一个订阅器列表,并实现注册、解注册和广播事件等方法。
- 定义订阅器接口,其中包含处理事件的方法。
- 创建多个具体订阅器类并实现订阅器接口,在其中定义处理不同类型事件的具体逻辑。
- 当某个对象需要发送消息时,调用中介者的广播事件方法,在该方法内部遍历所有订阅器,并根据不同类型调用对应订阅器的处理方法。
实现代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;// 中介者接口
interface Mediator {void register(String eventType, Subscriber subscriber);void unregister(String eventType, Subscriber subscriber);void broadcastEvent(String eventType, Object data);
}// 具体中介者类
class ConcreteMediator implements Mediator {private Map<String, List<Subscriber>> subscribers;public ConcreteMediator() {this.subscribers = new HashMap<>();}@Overridepublic void register(String eventType, Subscriber subscriber) {if (!subscribers.containsKey(eventType)) {subscribers.put(eventType, new ArrayList<>());}subscribers.get(eventType).add(subscriber);}@Overridepublic void unregister(String eventType, Subscriber subscriber) {if (subscribers.containsKey(eventType)) {subscribers.get(eventType).remove(subscriber);if (subscribers.get(eventType).isEmpty()) { // 如果没有订阅者,移除该事件类型的列表subscribers.remove(eventType);}}}@Overridepublic void broadcastEvent(String eventType, Object data) {if (subscribers.containsKey(eventType)) {for (Subscriber s : subscribers.get(eventType)) {s.handleEvent(data);}}}}// 订阅器接口
interface Subscriber {void handleEvent(Object data);}// 具体订阅器类A
class ConcreteSubscriberA implements Subscriber{@Overridepublic void handleEvent(Object data){System.out.println("ConcreteSubscriber A received: " +data );}}// 具体订阅器类B
class ConcreteSubscriberB implements Subscriber{@Overridepublic void handleEvent(Object data){System.out.println("ConcreteSubscriberB received: " +data );}
}public class Main {public static void main(String[] args) {ConcreteMediator mediator = new ConcreteMediator();Subscriber subscriberA = new ConcreteSubscriberA();Subscriber subscriberB = new ConcreteSubscriberB();mediator.register("event1", subscriberA);mediator.register("event2", subscriberB);// 发送事件通知mediator.broadcastEvent("event1", "Hello, how are you?");mediator.broadcastEvent("event2", "I'm fine, thank you!");// 解注册订阅器mediator.unregister("event1", subscriberA);// 再次发送事件通知,只有subscriberB会接收到mediator.broadcastEvent("event1","This message won't be received by any subscribers");mediator.broadcastEvent("event2","This message will be received by only one subscriber");}
}
在上述示例中,我们定义了一个中介者接口 Mediator 和具体实现类 ConcreteMediator。然后创建了两个订阅器类 ConcreteSubscribere A和 ConcreteSubscribere B,并在其中分别实现处理不同类型事件的具体逻辑。当需要发送消息时,调用中介者的广播事件方法,在该方法内部遍历所有订阅器,并根据不同类型调用对应订阅器的处理方法。