概念与特点
概念:
中介者模式是提供一个中介者来将对象与对象之间多对多的关系变成一对多的关系,以此来解耦对象之间的依赖。
中介者模式与房屋中介类似,现在买卖房屋都是通过中介完成,这样买卖双方就不会有太多的联系,而是将精力放在自己更重要的事情上。
特点:
- 降低了对象之间的耦合性,使得对象可以独立地被复用。
- 将对象之间一对多关联转变为一对一的关联。提高系统灵活性,使系统更利于拓展和维护。
结构与实现
结构:
中介者模式包含抽象中介者、具体中介者、抽象同事类和具体同事类。
抽象中介者:中介者接口,提供了同事对象注册和转发同事对象信息的抽象方法。
具体中介者:实现中介者接口,定义一个 list 来管理同事对象,协调各个同事对象之间的交互关系,因此它依赖同事角色。
抽象同事类:保存中介者对象,提供同事对象交互的抽象方法。实现所有相互影响的同事类的公共功能。
具体同事类:实现抽象同事类的抽象方法,当需要与其他同事对象交互时,由中介者对象负责。
案例:
使用中介者模式完成房产中介买卖方交易。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>React App</title>
</head>
<body>
<div><label for="">卖方张三说:</label><input type="text" id="sell"><button style="margin-left: 10px" id="sellSubmit">发布</button></div>
<div><label for="">买方李四说:</label><input type="text" id="buy"><button style="margin-left: 10px" id="buySubmit">发布</button></div>
<div style="margin-top: 20px;
border: 1px solid #ddd;
padding: 20px;
border-radius: 10px;
display: inline-block;">
<div style="text-align: center">公告台</div>
<div style="display: flex">
<div style="margin-top: 10px">
<span style="background: pink">卖方消息内容:</span>
<div id="sellContent"></div>
</div>
<div style="margin-left: 20px;margin-top: 10px">
<span style="background: blue">买房消息内容:</span>
<div id="buyContent"></div>
</div>
</div>
</div>
<script>
//抽象中介者-房地产中介公司
class Medium{
register(member){
}//客户注册
relay(from,ad){
}//转发
}
//具体中介者-韶关房地产交流平台
class EstateMedium extends Medium{
constructor(){
super();
this.list = []
}
//用户注册
register(member){
if(!this.list.includes(member)){
this.list.push(member);
member.setMedium(this);
}
}
//转发用户消息
relay(from,ad){
for(let i of this.list){
let name = i.getName();
if(name !== from){
i.receive(from,ad);
}
}
}
}
//抽象同事类-客户
class Qistomer{
constructor(name){
this.name = name;
}
setMedium(medium){
this.medium = medium;
}
getName(){
return this.name;
}
send(ad){
}
receive(from,ad){
}
}
//具体同事类-卖方
class Seller extends Qistomer{
constructor(name){
super(name);
this.name = name;
this.content = this.name+"说:"+"<br>";
}
send(ad){
this.content+=ad+"<br>";
sellContent.innerHTML = this.content;
this.medium.relay(this.name,ad);
}
receive(from,ad){
console.log("接收到一条消息"+from+"说:"+ad);
}
}
//具体同事类-买方
class Buyer extends Qistomer{
constructor(name){
super(name);
this.name = name;
this.content = this.name+"说:"+"<br>";
}
send(ad){
this.content+=ad+"<br>";
buyContent.innerHTML = this.content;
this.medium.relay(this.name,ad);
}
receive(from,ad){
console.log("接收到一条消息"+from+"说:"+ad);
}
}
class Customer{
static main(){
let md = new EstateMedium();
let member1 = new Seller("卖方(张三)");
let member2 = new Buyer("买方(李四)");
md.register(member1);
md.register(member2);
sellSubmit.onclick = function () {
member1.send(sell.value);
sell.value = "";
}
buySubmit.onclick = function () {
member2.send(buy.value);
buy.value = "";
}
}
}
Customer.main();
</script>
</body>
</html>
应用场景
- 当对象之间存在复杂的网状结构而导致依赖关系混乱难以复用时。 对象之间存在一对多的关系。一个对象的状态改变会影响其他状态的改变。
- 同事对象不持有中介者,而是在需要的时候直接获取中介者对象并调用。
应用实例
参考以上案例。
总结
中介者模式就是解耦对象多对多的依赖关系。使用第三方也就是中介方来使多个对象独立化。那么中介方必须提供对象注册,对象消息转发等功能。那样一来对象与对象之间,比如买卖方之间,只需要将自己的消息发布到平台(中介方)。由平台进行转发到其他对象,接收的消息也是来自于平台方。这样对象与对象之间就能很好地解耦。
【中介者】:
1、初始化 list 容器,用来管理同事对象。
2、提供注册同事对象的方法 register (调用setMedium方法)。
3、提供转发消息的方法 replay(调用同事对象的 receive 方法)。
【同事对象】:
1、在抽象类中定义 setMedium方法。
1、提供接收消息的方法 receive,
2、提供发送消息的方法 send(调用this.medium.replay)。