详解JAVA面向对象的设计模式 (五)、中介者模式

中介者模式(调停模式) Mediator

模式的定义与特点

中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介者模式是一种对象行为型模式,其主要优点如下。

  1. 降低了对象之间的耦合性,使得对象易于独立地被复用。
  2. 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

其主要缺点是:当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

模式的结构与实现

中介者模式实现的关键是找出“中介者”,下面对它的结构和实现进行分析。

模式的结构

中介者模式包含以下主要角色。

  1. 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
  2. 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
  3. 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
  4. 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

中介者模式的结构图

实现例子

既然是中介者模式,我们就写一个租房中介的例子。

  • 租房中介即中介者
  • 来自不同省份的准租客即同事
  • 某省份的准租客发送已认租信息后,中介者转发给所有注册的准租客
  • 所有准租客收到已出租信息
// 抽象中介
public abstract class AbstractMediator {
    public abstract void relay(AbstractTenant tenant);

    public abstract void register(AbstractTenant tenant);
}

// 抽象租客
public abstract class AbstractTenant {
    // 来自哪个省
    protected String province;
    // 指向的中介
    protected AbstractMediator mediator;

    public void setMediator(AbstractMediator mediator) {
        this.mediator = mediator;
    }

    public abstract void send();

    public abstract void receive(String msg);
}

具体类

// 具体中介
public class Mediator extends AbstractMediator {
    List<AbstractTenant> tenants = new ArrayList<>();

    @Override
    public void relay(AbstractTenant sender) {
        for (AbstractTenant t : tenants){
            if (t.equals(sender)) {
                continue;
            }
            t.receive("房子已经出租给" + sender.province + "租客");
        }
    }

    @Override
    public void register(AbstractTenant tenant) {
        if (!tenants.contains(tenant)) {
            tenants.add(tenant);
            tenant.setMediator(this);
        }
    }
}

// 具体租客(广东,四川,江西)
public class GuangdongTenant extends AbstractTenant {
    public GuangdongTenant() {
        province = "广东";
    }

    @Override
    public void send() {
        System.out.println(province + "租客发送认租信息!");
        mediator.relay(this);
    }

    @Override
    public void receive(String msg) {
        System.out.println("租房中介告知" + province + "准租户:" + msg);
    }
}
// 四川
public class SichuanTenant extends AbstractTenant {
    public SichuanTenant() {
        province = "四川";
    }

    @Override
    public void send() {
        System.out.println(province + "租客发送认租信息!");
        mediator.relay(this);
    }

    @Override
    public void receive(String msg) {
        System.out.println("租房中介告知" + province + "准租户:" + msg);
    }
}
//江西
public class JiangxiTenant extends AbstractTenant {
    public JiangxiTenant() {
        province = "江西";
    }

    @Override
    public void send() {
        System.out.println(province + "租客发送认租信息!");
        mediator.relay(this);
    }

    @Override
    public void receive(String msg) {
        System.out.println("租房中介告知" + province + "准租户:" + msg);
    }
}

由于例子的业务内容很简单,所以具体的send receive实现都一样,实际开发中可以灵活重写这2个方法。

测试一下

public static void main(String[] args) {
        AbstractTenant guangdongTenant = new GuangdongTenant();
        AbstractTenant sichuanTenant = new SichuanTenant();
        AbstractTenant abstractTenant = new JiangxiTenant();
        AbstractMediator mediator = new Mediator();
        mediator.register(guangdongTenant);
        mediator.register(sichuanTenant);
        mediator.register(abstractTenant);
        guangdongTenant.send();
    }

/**
输出:
广东租客发送认租信息!
租房中介告知四川准租户:房子已经出租给广东租客
租房中介告知江西准租户:房子已经出租给广东租客
*/
posted @ 2020-09-14 14:23  Rooooy7  阅读(538)  评论(0编辑  收藏  举报