介绍:用一个中介对象来封装对象的交互,中介者使各对象不需要显示地引用,从而使其耦合松散,而且可以独立地改变他们的交互。
场景:举个生活中的例子,如果我们去租房子,我们会将各个房源的价格留下来,等每次价格变动的时候,房东通知下面的各个有意向的房客,而我们又需要对每个房东进行反馈。这样,一个房客和每个房东,以及一个房东和每个房客的关系都紧密相连。如果我们通过中介,中介会帮我们处理这些事情,就显得相对简单。
一、角色及作用
角色 | 作用 |
---|---|
抽象同事 | 同事是指一些内部属性紧密相关的对象,当一个属性改变时,会尝试改变关联对象的相关内容,它们在定义时关联中介者 |
同事 | 实现具体的内容,以及和中介者的交互 |
抽象中介者 | 定义了改变时的方法 |
中介者 | 实现一个同事改变时所需要实现的业务 |
二、房东和房客
说明:针对上面场景的情况,为了方便房东和房客,我们引入中介者。这里实现同事和中介者之间的关联。
抽象同事类,关联中介
public abstract class Colleague {
protected Mediator mediator; // 绑定中介,不满意,随时可以更换
public Colleague(Mediator mediator) {
this.mediator = mediator;
mediator.addColleague(this );
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
}
房子
public class House extends Colleague {
private boolean flag = false; // 是否已经出租
private String name; // 房子名字
private int price; // 价格
public House(Mediator mediator, String name) { // 绑定中介和房屋名字
super(mediator);
this.name = name;
}
// 改变房价
public void changePrice(int price) {
this.price = price;
mediator.changed(this);
}
// 租房子
public boolean rentHouse(String name) {
if (flag) {
System.out.println(this.name + "已经出租");
return false;
} else {
System.out.println("房客" + name + "用" + this.price + "租下了" + this.name);
return true;
}
}
// getter and setter
}
房客
public class Lodger extends Colleague {
private String house; // 租的房子
private int staPrice; // 满意的价格
private String name; // 房客名字
// 绑定中介和房客名字及满意的价格
public Lodger(Mediator mediator, String name, int staPrice) {
super(mediator);
this.name = name;
this.staPrice = staPrice;
}
// 收到房子价格的信息
public void message(String house, int price) {
System.out.println(this.name + "收到中介信息---房子:" + house + ",租金:" + price);
if (this.staPrice == price) {
// 满意,租房子
this.house = house;
mediator.changed(this);
}
}
// getter and setter
}
三、中介出马
说明:中介主要的工作就是管理手头的房东和房客信息,当房价变更或者房客要买房的时候,就通知对应的房客和房东。
抽象中介者
public abstract class Mediator {
/**
* 同事对象有改变时,通知中介者的方法 在同事改变时,通过中介者,通知其他同事对象
*/
public abstract void changed(Colleague c);
/**
* 向中介者添加对象
*/
public abstract void addColleague(Colleague c);
}
房子中介
public class HouseMediator extends Mediator {
// 管理房子和房客信息
private List<Colleague> houses = new ArrayList<Colleague>();
private List<Colleague> lodgers = new ArrayList<Colleague>();
@Override
public void changed(Colleague c) {
if (c instanceof House) {
for (Colleague lodger : lodgers) {
message((House) c, (Lodger) lodger);
}
}
if (c instanceof Lodger) {
for (Colleague house : houses) {
House house2 = (House) house;
Lodger lodger = (Lodger) c;
if (house2.getName().equals(lodger.getHouse())) {
rentHouse((House) house, (Lodger) c);
}
}
}
}
@Override
public void addColleague(Colleague c) {
if (c instanceof House) {
houses.add(c);
}
if (c instanceof Lodger) {
lodgers.add(c);
}
}
public void message(House house, Lodger lodger) {
lodger.message(house.getName(), house.getPrice());
}
public void rentHouse(House house, Lodger lodger) {
house.rentHouse(lodger.getName());
}
}
四、开始工作
public static void main(String[] args) {
Mediator mediator = new HouseMediator();
House house1 = new House(mediator, "海边别墅");
House house2 = new House(mediator, "山中别墅");
Lodger lodger1 = new Lodger(mediator, "张三", 500);
Lodger lodger2 = new Lodger(mediator, "李四", 1000);
house1.changePrice(400);
System.out.println("=======");
house1.changePrice(500);
System.out.println("=======");
house2.changePrice(500);
System.out.println("=======");
house2.changePrice(1000);
}
输出
张三收到中介信息---房子:海边别墅,租金:400
李四收到中介信息---房子:海边别墅,租金:400
=======
张三收到中介信息---房子:海边别墅,租金:500
房客张三用500租下了海边别墅
李四收到中介信息---房子:海边别墅,租金:500
=======
张三收到中介信息---房子:山中别墅,租金:500
房客张三用500租下了山中别墅
李四收到中介信息---房子:山中别墅,租金:500
=======
张三收到中介信息---房子:山中别墅,租金:1000
李四收到中介信息---房子:山中别墅,租金:1000
房客李四用1000租下了山中别墅
总结:中介真的是帮了大忙,上边例子还可以为中介增加删除同事的方法,因为有些房客在租下房子后就不再需要接收信息。当对象间交互频繁,而且操作都彼此依赖,为防止在修改一个对象的行为时,同时涉及修改多个其他对象的行为,可用中介者模式来解决耦合问题。
更多模式:一天一个设计模式—分类与六大原则