一、介绍:
1、定义:中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来降低多个对象之间的耦合度。在中介者模式中,各个对象之间不直接进行通信,而是通过中介者对象进行协调和通信。
2、组成结构:
(1)抽象中介者(Abstract Mediator):定义了中介者对象的接口,用于协调各个同事对象之间的交互。
(2)具体中介者(Concrete Mediator):实现了抽象中介者接口,负责协调各个同事对象的交互,并了解各个同事对象的具体实现。
(3)抽象同事类(Abstract Colleague):定义了同事对象的接口,通常持有一个中介者对象的引用,用于与中介者进行通信。
(4)具体同事类(Concrete Colleague):实现了抽象同事类的接口,实现自身的业务逻辑,并通过中介者对象进行与其他同事对象的通信。
// 抽象中介者
interface Mediator {
void send(String message, Colleague colleague);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private Colleague colleague1;
private Colleague colleague2;
public void setColleague1(Colleague colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(Colleague colleague2) {
this.colleague2 = colleague2;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.receive(message);
} else {
colleague1.receive(message);
}
}
}
// 抽象同事类
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
}
// 具体同事类
class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("ConcreteColleague1 Received: " + message);
}
}
class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("ConcreteColleague2 Received: " + message);
}
}
// 客户端
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.send("msg from Colleague1");
colleague2.send("msg from Colleague2");
}
3、优点:
(1)降低耦合度:中介者模式将对象之间的交互集中在中介者对象中,减少了对象之间的直接依赖和耦合度,使系统更加灵活、可扩展和易于维护。
(2)简化对象间的通信:中介者模式通过引入中介者对象,将对象间复杂的相互通信转变为对象与中介者之间的简单交互,简化了对象间的通信逻辑。
(3)集中控制逻辑:中介者模式将对象间的交互逻辑集中在中介者对象中,使得系统的控制逻辑更加清晰明确。通过定义中介者对象来协调对象间的交互,可以更方便地修改和扩展系统的行为。
(4)促进代码重用:中介者模式将公共的交互逻辑封装在中介者对象中,可以被多个对象共享和复用,避免了代码的重复编写,提高了代码的可维护性和可复用性。
4、适用场景:
(1)当一个系统中对象之间存在复杂的相互关系,导致对象间的交互逻辑难以维护和扩展时,可以考虑使用中介者模式来简化交互逻辑。
(2)当一个对象需要对多个对象进行操作或通知时,可以引入中介者模式来集中管理这些对象之间的交互。
(3)当系统中的对象之间存在循环依赖关系,不方便直接进行交互时,可以通过引入中介者对象来解决循环依赖问题。
二、demo:
1、房租中介:三个房东、三个租客。房东类和租客类互相影响,称为同事类。
(1)抽象同事类
import java.util.Objects;
/**
* 抽象同事类(这里指房东、租客),有用户名称,以及消息发送、接收功能
*/
public abstract class Colleague {
//租客、房东 都认识中介
Mediator mediator;
public String userName;
public Colleague(String userName, Mediator mediator){
this.userName = userName;
this.mediator = mediator;
}
//这里对userName做equals和hashCode,是为了后面可以用contains判断方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Colleague colleague = (Colleague) o;
return Objects.equals(userName, colleague.userName);
}
@Override
public int hashCode() {
return Objects.hash(userName);
}
public void sendMsg(String msg){
System.out.println("我"+this.userName+"发送消息");
}
public void receiveMsg(String msg,Colleague fromColleague){}
}
(2)具体同事类,房东和租客
//房东类
public class LandlordColleague extends Colleague{
public LandlordColleague(String userName, Mediator mediator) {
super(userName,mediator);
}
//发送消息,需要通知谁 谁可以收到由中介完成
@Override
public void sendMsg(String msg) {
super.sendMsg(msg);
mediator.notice(msg,this);
}
//收到中介发送的消息
@Override
public void receiveMsg(String msg,Colleague fromColleague) {
System.out.println("房东"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);
}
}
import java.util.List;
//租客同事类
public class TenantColleague extends Colleague {
public TenantColleague(String userName, Mediator mediator) {
super(userName,mediator);
}
//发送消息,谁可以收到(所有房东)由中介完成
@Override
public void sendMsg(String msg) {
super.sendMsg(msg);
mediator.notice(msg,this);
}
//收到消息
@Override
public void receiveMsg(String msg,Colleague fromColleague) {
System.out.println("租客"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);
}
}
(3)抽象中介
//抽象中介
public interface Mediator {
//通知
void notice(String msg,Colleague fromColleague);
}
(4)具体中介
import java.util.ArrayList;
import java.util.List;
/**
* 房租中介
*/
public class RentMediator implements Mediator{
//所有租客
List tenantColleagues = new ArrayList<>();
//所有房东
List landlordColleagues = new ArrayList<>();
//添加房东
void addLandlord(Colleague colleague){
this.landlordColleagues.add(colleague);
}
//添加租客
void addTenantColleague(Colleague colleague){
this.tenantColleagues.add(colleague);
}
/**
* 通知
* 通知所有房东or 租客
* @param msg
* @param fromColleague
*/
@Override
public void notice(String msg, Colleague fromColleague) {
//房东发的,通知所有租客
if(landlordColleagues.contains(fromColleague)){
for(Colleague colleague : tenantColleagues){
colleague.receiveMsg(msg,fromColleague);
}
}
//租客发的,通知所有房东
if(tenantColleagues.contains(fromColleague)){
for(Colleague colleague : landlordColleagues){
colleague.receiveMsg(msg,fromColleague);
}
}
}
}
客户端:
public class Test {
public static void main(String args[]){
RentMediator rentMediator = new RentMediator();
//房东管理
LandlordColleague landlordColleague1 = new LandlordColleague("房东1",rentMediator);
LandlordColleague landlordColleague2 = new LandlordColleague("房东2",rentMediator);
LandlordColleague landlordColleague3 = new LandlordColleague("房东3",rentMediator);
rentMediator.addLandlord(landlordColleague1);
rentMediator.addLandlord(landlordColleague2);
rentMediator.addLandlord(landlordColleague3);
//租客管理
TenantColleague tenantColleague1 = new TenantColleague("租客1",rentMediator);
TenantColleague tenantColleague2 = new TenantColleague("租客2",rentMediator);
TenantColleague tenantColleague3 = new TenantColleague("租客3",rentMediator);
rentMediator.addTenantColleague(tenantColleague1);
rentMediator.addTenantColleague(tenantColleague2);
rentMediator.addTenantColleague(tenantColleague3);
//
tenantColleague2.sendMsg("寻找三室房源");
System.out.println("******");
landlordColleague3.sendMsg("发布新房源");
}
}
输出:
我租客2发送消息
房东房东1收到租客2发送的消息寻找三室房源
房东房东2收到租客2发送的消息寻找三室房源
房东房东3收到租客2发送的消息寻找三室房源
******
我房东3发送消息
租客租客1收到房东3发送的消息发布新房源
租客租客2收到房东3发送的消息发布新房源
租客租客3收到房东3发送的消息发布新房源