中介者模式是指用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
适合中介者模式的情景如下:许多对象以复杂的方式交互,所导致的依赖关系使系统难以维护;一个对象引用其他很多对象,导致难以复用该对象。
生活中有各种各样的中介机构,这些中介机构给我们的生活带来了诸多便利。例如:房屋中介机构,可以方便租房和卖房。
让我们通过一个具体实例,加深理解中介者设计模式。仍以房屋中介功能为例,实现的功能是:
- 租房者发布租房信息至房屋中介,房屋中介将收到的信息发布给所有的出租房屋者。
- 出租房屋者发布信息至房屋中介,房屋中介将收到的信息发布给所有租房者。
Renter.java:租房者
public class Renter {
private String NO;
private String name;
private Mediator me;
public Renter(String N, String na, Mediator me) {
this.NO = N;
this.name = na;
this.me = me;
}
public String getNO() {
return NO;
}
public String getName() {
return name;
}
public void receive(String msg) {
System.out.println(NO+"\t"+name+"receive:");
System.out.println("\t"+msg);
}
public void send(String msg) {
me.send(this, msg);
}
}
成员变量NO、Name代表求租者账号、姓名。由于求租者要与中介者通信,因此成员变量包含了中介者Mediator类对象的引用me。receive()方法用于求租者接收来自中介者的信息;send()方法用于求租者向中介者发信息。
Saler.java:出租者类
public class Saler {
private String NO;
private String name;
private Mediator me;
public Saler(String no, String name, Mediator me) {
this.NO = no;
this.name = name;
this.me = me;
}
public String getNO() {
return NO;
}
public String getName() {
return name;
}
public void receive(String msg) {
System.out.println(NO+"\t"+name+"receive:");
System.out.println("\t"+msg);
}
public void send(String msg) {
me.send(this, msg);
}
}
成员变量NO、Name代表出租者账号、姓名。由于出租者要与中介者通信,因此成员变量包含了中介者Mediator类对象的引用me。receive()方法用于出租者接收来自中介者的信息;send()方法用于出租者向中介者发信息。
public class Mediator {
Map<String, Renter> m = new HashMap<>();
Map<String, Saler> m2 = new HashMap<>();
public void addRenter(Renter r) {
m.put(r.getNO(), r);
}
public void addSaler(Saler s) {
m2.put(s.getNO(), s);
}
public void send(Renter r, String msg) {
System.out.println("come from renter-"+r.getNO()+"-"+r.getName());
System.out.println("\t"+msg);
Set<String> se = m2.keySet();
Iterator<String> it = se.iterator();
while(it.hasNext()) {
String key = it.next();
Saler sa = m2.get(key);
sa.receive(r.getNO()+"-"+r.getName()+"-"+msg);
}
}
public void send(Saler s, String msg) {
System.out.println("come from saler-"+s.getNO()+"-"+s.getName());
System.out.println("\t"+msg);
Set<String> se = m.keySet();
Iterator<String> it = se.iterator();
while(it.hasNext()) {
String key = it.next();
Renter r = m.get(key);
r.receive(s.getNO()+"-"+s.getName()+"-"+msg);
}
}
}
这是中介者模式的核心类。由于中介者必须知道所有求租者和出租者的信息,因此定义了求租者集合Map<String,Renter>成员变量m以及出租者集合Map<String,Renter>成员变量m2。addRenter()方法用于向集合m添加新的求租者对象;addSaler()方法用于向集合m2添加新的出租者对象。send(Renter r, String msg)方法用于接收求租者发送的信息,并向所有出租者广播。send(saler s, String msg)方法用于接收出租者发送的信息,并向所有求租者广播。
Test.java:测试类
public class Test {
public static void main(String[] args) {
Mediator me = new Mediator();
Renter r = new Renter("1000", "li", me);
Saler s = new Saler("2000", "sun", me);
Saler s2 = new Saler("2001", "sun2", me);
me.addRenter(r);
me.addSaler(s);
me.addSaler(s2);
r.send("I want to rent a house");
s.send("I want to sale a house");
s2.send("I want to sale a house");
}
}
测试结果:
come from renter-1000-li
I want to rent a house
2001 sun2receive:
1000-li-I want to rent a house
2000 sunreceive:
1000-li-I want to rent a house
come from saler-2000-sun
I want to sale a house
1000 lireceive:
2000-sun-I want to sale a house
come from saler-2001-sun2
I want to sale a house
1000 lireceive:
2001-sun2-I want to sale a house