定义

中介者模式就是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

角色:

  • Mediator: 抽象中介者。定义了同事对象到中介者对象之间的接口。

  • ConcreteMediator: 具体中介者。实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。

  • Colleague: 抽象同事类。

  • ConcreteColleague: 具体同事类。每个具体同事类都只需要知道自己的行为即可,但是他们都需要认识中介者。

注:对象之间存在大量的多对多联系,将导致系统非常复杂,这些对象既会影响别的对象,也会被别的对象所影响,这些对象称为同事对象,它们之间通过彼此的相互作用实现系统的行为。

在中介者模式中中介者对象处于核心地位,因为它定义了整个系统中所有具体同事类之间的关系。在整个系统中它主要承担两个方面的责任。

  • 1、 结构上起到中转作用。通过中介者对象对关系的封装,使得具体的同事类不再需要显示的引用其他对象,它只需要通过中介者就可以完成与其他同事类之间的通信。

  • 2、 行为上起到协作作用。中介者对同事类之间的关系进行封装,同事类在不需要知道其他对象的情况下通过中介者与其他对象完成通信。在这个过程中同事类是不需要指明中介者该如何做,中介者可以根据自身的逻辑来进行协调,对同事的请求进一步处理,将同事成员之间的关系行为进行分离和封装。

同时由于中介者对对象的关系进行了封装,使得各个同事类之间的耦合减少了,使得他们可以独立改变和复用。

优缺点

优点:

  • 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。
  • 提供系统的灵活性,使得各个同事对象独立而易于复用。

缺点:

中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。
新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。

实例

租房

中介者抽象类:

/**
 * 中介者抽象类
 */
public abstract class Mediator {
    public abstract void constact(String message,Person person);
}

同事对象基类:

public class Person {

    protected String name;
    protected Mediator mediator;

    Person(String name,Mediator mediator){
        this.name = name;
        this.mediator = mediator;
    }
}

具体同事类:

/**
 * 房东
 */
public class HouseOwner extends Person{

    HouseOwner(String name, Mediator mediator) {
        super(name, mediator);
    }

    /**
     * @desc 与中介者联系
     * @param message
     * @return void
     */
    public void constact(String message){
        mediator.constact(message, this);
    }

    /**
     * @desc 获取信息
     * @param message
     * @return void
     */
    public void getMessage(String message){
        System.out.println("房东:" + name +",获得信息:" + message);
    }
}

/**
 * 租客
 */
public class Tenant extends Person{

    Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }

    /**
     * @desc 与中介者联系
     * @param message
     * @return void
     */
    public void constact(String message){
        mediator.constact(message, this);
    }

    /**
     * @desc 获取信息
     * @param message
     * @return void
     */
    public void getMessage(String message){
        System.out.println("租客:" + name +",获得信息:" + message);
    }
}

具体中介:

/**
 * 具体中介
 */
public class MediatorStructure extends Mediator {
    // 中介必须知道所有房东和租客的信息
    private HouseOwner houseOwner;
    private Tenant tenant;

    public HouseOwner getHouseOwner() {
        return houseOwner;
    }

    public void setHouseOwner(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }

    public Tenant getTenant() {
        return tenant;
    }

    public void setTenant(Tenant tenant) {
        this.tenant = tenant;
    }

    public void constact(String message, Person person) {
        //如果是房东,则租客获得信息。反之则是房东获得信息
        if (person == houseOwner) {
            tenant.getMessage(message);
        } else {
            houseOwner.getMessage(message);
        }
    }
}

测试:

public static void main(String[] args) {
    //一个房东、一个租客、一个中介
    MediatorStructure mediator = new MediatorStructure();
    //房东和租客只需要知道中介即可
    HouseOwner houseOwner = new HouseOwner("张老三", mediator);
    Tenant tenant = new Tenant("李小四", mediator);

    //中介要知道房东和租客
    mediator.setHouseOwner(houseOwner);
    mediator.setTenant(tenant);

    tenant.constact("听说你那里有三室的房子出租.....");
    houseOwner.constact("是的!请问你需要租吗?");
}

控制台输出:

房东:张老三,获得信息:听说你那里有三室的房子出租.....
租客:李小四,获得信息:是的!请问你需要租吗?
02-12 02:02