定义
中介者模式(Mediator pattern) : 使用中介者模式来集中相关对象之间复杂的沟通和控制方式,使得这些对象不必相互明显引用。从而使它们可以较松散地耦合。当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立地变化。
场景
下图中有6个对象,这些对象既会影响别的对象,又会被别的对象所影响,因此常常叫做同事(Colleague)对象。这些同事对象通过彼此的相互作用形成系统的行为。从图中可以看出,当对象1改变时,除了对象3之外其他所有对象都有可能受到影响;当对象2改变时,所有对象都有可能受到影响。这就是过度耦合的系统。
通过引入中介者(Mediator),那么同事类之间的关系将变成星型结构。如下图所示,在这个星型结构中,同事对象不再通过直接的联系与另一个对象发生相互作用;相反的,它通过中介者对象与另一个对象发生相互作用。中介者对象的存在保证了对象结构上的稳定,也就是说,系统的结构不会因为新对象的引入造成大量的修改工作。
现实中的示例: 房东,房屋中介,租客。代码中:服务和注册中心。
教科书版本
类图
实现
详细见:com.haiwei.behavior.mediator.mediator1
public class Client {/*** @param args*/// 中介者,ColleagueA、ColleagueBpublic static void main(String[] args) {// 定义中介者ConcreteMediator mediator = new ConcreteMediator();// 定义具体同事类ColleagueA colleagueA = new ColleagueA("张三", mediator);ColleagueB colleagueB = new ColleagueB("李四", mediator);// 中介者知晓每一个具体的Colleague类mediator.setCollA(colleagueA);mediator.setCollB(colleagueB);colleagueA.contact("我是A,我要和同事B说说工作的事情");colleagueB.contact("我是B,我下午有时间,下午商量吧");}}
缺点
没有使用价值
从类图上或者从代码调用上看不出服务间的交互关系的变化,没有很好的体现中介者的思想
同事没法动态添加,新加一个同事还需要新增加一个方法和一个熟悉,违反开闭原则
调用规则已经固定,有时候你并不知道需要找谁,比如:你租房的场景,找那个房东你并不知道,知道了联系哪个房东,我要你中介干么事
实用版本
场景:租房
- 如果没有中介,房东需要到处粘贴出租信息 – 房东不知道 他将跟谁通信
- 如果没有中介,租客会挨个小区看出租信息,然后联系房东 – 租户并不知道,他联系的房东是谁,挨个遍历
- 引入中介,房东把信息注册给中介公司,租客去中介公司租房
- 中介按照租客的要求,给租客推荐房屋信息,租客看好后,中介联系房东进行看房
- 有的中介会给你房东的信息,然后你跟房东联系;有的中介不会给你房东的信息,他自己替你联系房东。这都是中介模式,根据实际需求定吧。
分析
- 角色:租客(Tenant),中介(Mediator),房东(Landlord)
- 中介有两个动作:房东注册房屋信息;租客根据需求获取房屋信息,也可以说中介根据租客需求寻找房屋,并联系房东
- 是房屋注册给中介,房东只是房屋的属性(归属)
- 下面代码就让中介联系房东,你自己联系房东的场景可以自己变形
类图
实现
(com.haiwei.behavior.mediator.mediator2)
调用流程 – 替换中介者
public class Client {public static void main(String[] args) {//1. 创建房屋对象TwoRoomedHouse tow = new TwoRoomedHouse(2,new Loadlord("王二"));ThreeRoomedHouse three = new ThreeRoomedHouse(3,new Loadlord("张三"));//2.将房屋注册给房屋中介HousingIntermediary mediary = new HousingIntermediary();mediary.registedHouse(tow);mediary.registedHouse(three);//3.创建租客对象Tenant t = new Tenant(2);//4&5.房屋中介 映射 房屋并跟房东通信mediary.mapHouseAndCotactLoadlord(t.getRentHousingSize(), "你房子多少钱");}
}
房屋信息
public abstract class House {public int size;public Loadlord landlord ;public House(int size, Loadlord landlord) {this.size = size;this.landlord = landlord;}
}
/*** 三居室*/
public class ThreeRoomedHouse extends House {public ThreeRoomedHouse(int size, Loadlord landlord) {super(size, landlord);}
}
/*** 两居室*/
public class TwoRoomedHouse extends House {public TwoRoomedHouse(int size, Loadlord landlord) {super(size, landlord);}
}
中介者
/*** 中介者接口*/
public interface Mediator {public void registedHouse(House house);public void mapHouseAndCotactLoadlord(Integer size,String msg);
}
/*** 房屋中介*/
public class HousingIntermediary implements Mediator {private Map<Integer,House> registedHouseMap = new HashMap<>();/*** 注册房屋*/public void registedHouse(House house) {registedHouseMap.put(house.size, house);}/*** 根据某种规则映射房屋并联系房东* 这是简单的房屋大小匹配的,实际按照各自逻辑匹配就行*/public void mapHouseAndCotactLoadlord(Integer size,String msg) {registedHouseMap.get(size).landlord.reviewMessage(msg);}
}
房东
/*** 房东* 当然可以添加一个接口*/
public class Loadlord {private String name;public Loadlord(String name) {this.name = name;}public void reviewMessage(String msg){System.out.println("房东:"+ name + ",收到消息:"+msg);}
}
附录
暂无