引言
假设有老赵、老钱、老孙三位房东,他们自己手里有一套房租需要出租,但是又有不同的需求,于是相互商量:
可是出租房子的人毕竟很多,哪种房型好租,租什么价格需要了解很多出租情况,而自己要与那么多人交流需要花费很大的时间与精力……所以他们都不约而同地找到了中介,将自己房子出租的信息放到了中介,让中介去和租客交互,自己有什么问题也可以直接找中介问,还能躺着收房租,只需要和中介打交道就可以了。
这就是中介者模式的应用场景。
中介者模式
定义
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
通用类图
Mediator 抽象中介者角色
抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
Concrete Mediator 具体中介者角色
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
Colleague 同事角色
每一个同事角色都知道中介者角色,而且与其他同事角色通信的时候,一定要通过中介者角色协作。协作分为两种,一种是本身的行为,比如自己状态变化,独立可以完成的行为;另一种是必须依赖中介者才能完成的行为,比如与其他同事角色通信。
中介者例子
前提条件
老赵、老钱、老孙的房子信息如下:
- 老赵:一套一室一厨一卫房子
- 老钱:一套一室一厅一卫的房子
- 老孙:一套两室一厅一厨一卫的房子
老赵感觉自己房子(一室一厨一卫)比老钱房子(一室一厅一卫)好出租,想比老钱的房子多租100元,如果老钱不告诉他自己的价格,那么老赵就准备按2500出租;
老钱就想租2500,且想知道老赵和老孙的房子出租的信息;
老孙觉得自己房子适合一家人住一起,想租3600,并且自己想知道小户型房子(老赵和老孙房子)出租情况;
关系类图
Mediator:抽象中介者
LettingAgent:具体的中介者实现
AbstractLessor:抽象的同事类(非必须)
XXXLessor:具体的同事类(多个出租人之间关系对等,类似同事关系)
代码实现
对于中介mediator来说,它指定老赵、老钱、老孙的信息,他们可以通过询问中介来知道自己想知道的事情,不需要单独分别去问另外两人,对象之间的依赖更简单了,中介实现如下:
public abstract class Mediator { protected MrZhaoLessor mrZhaoLessor; protected MrQianLessor mrQianLessor; protected MrSunLessor mrSunLessor; public Mediator(){ this.mrZhaoLessor = new MrZhaoLessor(this); this.mrQianLessor = new MrQianLessor(this); this.mrSunLessor = new MrSunLessor(this); } public MrZhaoLessor getMrZhaoLessor() { return mrZhaoLessor; } public void setMrZhaoLessor(MrZhaoLessor mrZhaoLessor) { this.mrZhaoLessor = mrZhaoLessor; } public MrQianLessor getMrQianLessor() { return mrQianLessor; } public void setMrQianLessor(MrQianLessor mrQianLessor) { this.mrQianLessor = mrQianLessor; } public MrSunLessor getMrSunLessor() { return mrSunLessor; } public void setMrSunLessor(MrSunLessor mrSunLessor) { this.mrSunLessor = mrSunLessor; } public abstract String getZhaoAndQianInfo(); public abstract String getZhaoAndSunInfo(); public abstract String getQianAndSunInfo(); public abstract String getAllRoomInfo(); public abstract String getAllRoomPrice(); }
具体中介者实现了抽象中介者的方法:
public class LettingAgent extends Mediator { @Override public String getAllRoomInfo() { String roomInfo = "我手里有这几种房型: " + super.getMrZhaoLessor().roomInfo() + " " + super.getMrQianLessor().roomInfo() + " " + super.getMrSunLessor().roomInfo(); return roomInfo; } @Override public String getAllRoomPrice() { String roomPrice = super.getMrZhaoLessor().roomInfo() + ",价格:" + super.getMrZhaoLessor().roomPrice() + " " + super.getMrQianLessor().roomInfo() + ",价格:" + super.getMrQianLessor().roomPrice() + " " + super.getMrSunLessor().roomInfo() + ",价格:" + super.getMrSunLessor().roomPrice(); return roomPrice; } @Override public String getZhaoAndQianInfo(){ String otherRoom = super.getMrZhaoLessor().roomInfo() + ",价格:" + super.getMrZhaoLessor().roomPrice() + " " + super.getMrQianLessor().roomInfo() + ",价格:" + super.getMrQianLessor().roomPrice(); return otherRoom; } @Override public String getZhaoAndSunInfo(){ String otherRoom = super.getMrZhaoLessor().roomInfo() + ",价格:" + super.getMrZhaoLessor().roomPrice() + " " + super.getMrSunLessor().roomInfo() + ",价格:" + super.getMrSunLessor().roomPrice(); return otherRoom; } @Override public String getQianAndSunInfo(){ String otherRoom = super.getMrQianLessor().roomInfo() + ",价格:" + super.getMrQianLessor().roomPrice() + " " + super.getMrSunLessor().roomInfo() + ",价格:" + super.getMrSunLessor().roomPrice(); return otherRoom; } }
可以根据出租人之间是否有相同需求来决定是否需要增加出租人抽象接口
public abstract class AbstractLessor { protected Mediator mediator; public AbstractLessor(Mediator mediator){ this.mediator = mediator; } }
老赵的实现如下:
public class MrZhaoLessor extends AbstractLessor { public MrZhaoLessor(Mediator mediator) { super(mediator); } public String roomInfo() { return "老赵的一室一厨一卫"; } public BigDecimal roomPrice() { BigDecimal roomWithKitchAndToiletPrice = super.mediator.getMrQianLessor().roomPrice(); if (roomWithKitchAndToiletPrice == null) { //自己内心价格 return BigDecimal.valueOf(2500); } return roomWithKitchAndToiletPrice.add(BigDecimal.valueOf(100)); } public String talk() { return "很好租,独立厨房卫生间"; } }
老钱与老孙实现差不多,以老钱为例:
public class MrQianLessor extends AbstractLessor { public MrQianLessor(Mediator mediator) { super(mediator); } public String roomInfo() { return "老钱的一室一厅一卫"; } public BigDecimal roomPrice() { return BigDecimal.valueOf(2500); } public String askOtherRoomInfo() { return super.mediator.getZhaoAndSunInfo(); } }
老赵与老钱通过中介交互:
LettingAgent agent = new LettingAgent(); MrZhaoLessor zhaoLessor = new MrZhaoLessor(agent); BigDecimal zhaoPrice = zhaoLessor.roomPrice(); String talk = zhaoLessor.talk(); System.out.println(">>>赵先生: " + zhaoPrice + ", " + talk+" "); MrQianLessor qianLessor = new MrQianLessor(agent); String qianRoom = qianLessor.askOtherRoomInfo(); System.out.println(">>>钱先生: " + qianRoom+" ");
>>>赵先生:
2600,
很好租,独立厨房卫生间
>>>钱先生:
老赵的一室一厨一卫,价格:2600
老孙的两室一厅一厨一卫,价格:3600
总结
优点:减少类之间的依赖,引入中介者将原来多对多依赖便成了一对一,降低了类之间的耦合性。
缺点:中介者封装了不同对象之间的依赖关系,当对象增多,中介者会变得很复杂,同事类越多中介者越复杂。
参考:本文demo