定义
defines an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets us vary their interaction independently.
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
实列
生活中,有很多类似于租房中介、聊天室、交警、消息中间件这样的对象,它们位于一些有彼此关联的对象中间,扮演协调者的角色。
比如说,位于租客和房东之间的租房中介,如果没有它的存在,那么一个租客就要和多个房东打交道,这种一对多的关系会增加租客找房的复杂度;
反之,租客找房只需和中介打交道,而中介再去和多个可复用的房东打交道,这样就能大大提高租房市场的劳动效率。
再比如,你开车行驶到到一个没有红绿灯的十字路口,如果有交警那你只需和交警建立联系,反之就需要和其它司机彼此之间建立联系,否则肯定是一片混乱。
所以,可以看出,这些中间对象可以将二元的多对多关系转换成三元的多对一对多的关系,从而降低了双方的复杂度。
故事
昨天,我和公司一同事吵了一架。
事情是这样的:他负责订单组件,我负责支付组件,另一个同事负责库存组件;
当用户支付成功时,支付组件要调用订单组件通知它订单已支付,然后订单组件要通知库存组件扣减库存;
但是,他负责的订单组件昨天常规发版,但没有告知我他修改了支付回调的方法,导致我这边回调订单组件异常,最终导致用户订单实际支付了但订单显示未支付。
事后进行订单数据修复,还发现了大量的商品被超卖。
因此,领导认为这锅在我要我背着,而背锅的代价是这个月的绩效。
下面是伪代码:
/**支付组件*/
public class Payment {
//依赖订单组件
protected Order order;
public Payment(Order order){
this.order = order;
}
public void pay(){
order.paySuccess();
}
}
/**订单组件*/
public class Order {
//依赖库存组件
protected Inventory inventory;
public Order(Inventory inventory){
this.inventory = inventory;
}
public void paySuccess(){
inventory.decrease();
}
}
/**库存组件*/
public class Inventory {
public void decrease(){
System.out.println("库存扣减");
}
}
问题
故事中,当订单支付成功时,支付对象通过直接交互的方式来通知订单对象,订单通知库存也是同样的方式。
如果继续往系统中增加优惠券、商品、物流等大量的组件,那么便会出现一个对象直接与多个对象交互的情况,它们之间的关系便会形成网状结构。
这种网状结构的关系增加了系统的复杂度,很容易导致系统维护困难,牵一发而动全身。
比如说,某个对象的交互方法名修改了,那么很有可能需要修改所有与它交互的对象。
所以,有没有一种方式可以简化对象间的交互关系?可以将直接交互转换成间接交互,这便是中介者模式。
方案
中介者模式通过一个中介者,将对象间的直接交互关系转换成了间接交互关系,这个中介者封装了对象间的交互行为。
对象不再直接与其目标对象交互,而是间接地通过中介者将请求转发给目标对象,在中介者模式中这些对象被称之为同事。
这种间接的交互方式将对象间的网状结构关系变成了星状结构,大大降低了系统的复杂度。
比如说,当一个同事类发生修改时,不需要修改与之通信的同事类而只需要修改中介者,因为同事之间彼此都不知道对方的存在。
应用
接下来,我们使用状态模式重构一下故事中的程序。
首先,创建一个中介者,将对象间的交互行为封装到这个类中。
/**中介者*/
public class Mediator {
protected Order order;
protected Inventory inventory;
public Mediator(Order order,Inventory inventory){
this.order=order;
this.inventory=inventory;
}
public void notifyOrder(){
order.paySuccess();
}
public void notifyInventory(){
inventory.decrease();
}
}
然后,让有交互的同事类只引用中介者,并将交互请求委托给它。
/**订单组件*/
public class Order {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void paySuccess(){
mediator.nofityInventory();
}
}
/**支付组件*/
public class Payment {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void pay(){
mediator.notifyOrder();
}
}
/**库存组件*/
public class Inventory {
public void decrease(){
System.out.println("库存扣减");
}
}
最后,我们看看客户端如何使用中介者模式来解藕对象间的直接依赖关系。
/**客户端*/
public class Client {
public static void main(String[] args) {
Order order = new Order();
Inventory inventory = new Inventory();
Payment payment = new Payment();
Mediator mediator = new Mediator(order,inventory);
payment.setMediator(mediator);
order.setMediator(mediator);
payment.pay();
}
}
结构
![](https://img.haomeiwen.com/i9996080/49f1c10f6ff6ed23.gif)
抽象中介者角色(Mediator) :它声明了同事对象与具体中介对象交互的接口。
具体中介者角色(ConcreteMediator):它持有指向同事对象的引用,并封装了和同事对象的交互行为。
同事角色(Colleague) :它持有一个指向中介对象的引用,并将交互请求委托给中介者。
总结
当对象间存在复杂的直接交互关系时,为了避免系统复杂度增加以及难以维护,我们可以使用中介者模式将直接交互变成间接交互。
这样,可以避免对象之间之间耦合,降低系统的复杂度,防止一个对象的修改影响多个对象。
网友评论