likes
comments
collection
share

【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

作者站长头像
站长
· 阅读数 4

前言

八小时内某生存,八小时外某发展。

继续走我们的设计模式,今天来到中介者模式专场。

一、概述

【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

1.1 概念

中介者模式,从名字上我们再熟悉不过了,中介充当中间人的角色。对象与对象之间不再直接对接,通过中介来做桥梁,事实上也是这样的。目的嘛,就是解耦呗,貌似大多数设计模式搞的很复杂,就是为了解耦和程序的拓展性。

看看百科的定义:

中介者模式是为了“定义一个封装了对象间交互关系的对象”。这种方式避免了显式调用其他类,促进了类间的松耦合,并且使得类间交互关系本身可以单独修改

中介者模式:解决复杂功能应用之间的重复调用。

在这中间添加一层中介者包装服务,对外提供简单、通用、容易拓展的服务。

【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

UML 的类图和时序图如上。

Mediator 是 中介的概念。Colleague 是同事的概念。

可以看到由 Mediator1 来通知具体同事做某些动作,而同事与同事之间并无关联关系。

看到这个类图里面用的角色居然是同事,说明 GoF 设计者也觉得同事之间的关系太过复杂,如果同事众多的话,两两组合,那就是网状结构了,同事之间互相耦合,如果采用中介者,所有同事都去找中介者,那如果某个同事离职了,就不用去改动其他同事的影响变化,只需要修改中介者就行。

这样,中介者就诞生了,我们的关系结构也变成星型结构。

【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

由 “群魔乱舞” 形式转为 “朝拜天子”。

1.2 结构

【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

再来看看类图,存在四种角色。

  • Mediator : 充当抽象中介者的概念,定义各个同事之间交互的接口

  • ConcreteMediator :充当具体中介者角色,实现 Mediator 的接口,必须要知道所有同事对象,且协调它们交互,因此,它需要依赖同事对象,可定义一个List来管理同事对象。

  • Colleague: 充当抽象同事角色,定义所有同事类的公共功能

  • ConcreteColleague:充当具体同事类,当需要与其他同事对象交互时,由中介者对象负责交互。

二、案例引入

就拿同事举例。

项目经理需要跨部门,跨公司协调项目进度。

参与方有:

  • 施工人员A

  • 技术人员B

  • 软件人员C

abstract class Colleague {
    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void sendMessage(String message);

    public abstract void receiveMessage(String message);
}

具体同事

class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("施工人员 received message: " + message);
    }
}
class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("技术人员 received message: " + message);
    }
}
class ConcreteColleague3 extends Colleague {
    public ConcreteColleague3(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("软件人员 received message: " + message);
    }
}

中介者

public interface Mediator {
    void sendMessage(String message, Colleague colleague);
}
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues;

    public ConcreteMediator() {
        colleagues = new ArrayList<>();
    }

    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }

    @Override
    public void sendMessage(String message, Colleague colleague) {
        for (Colleague c : colleagues) {
            if (c != colleague) {
                c.receiveMessage(message);
            }
        }
    }
}

打印信息

技术人员 received message: Hello from 施工人员
软件人员 received message: Hello from 施工人员
施工人员 received message: Hello from 技术人员
软件人员 received message: Hello from 技术人员
施工人员 received message: Hello from 软件人员
技术人员 received message: Hello from 软件人员

三、总结

优点:

  • 中介者模型将通过同事对象都封装到中介者对象中,从而使得同事对象之间松散耦合,同事对象可以独立的变化和复用,只需修改中介者即可。
  • 将一对多的关系转成一对一的关系

缺点:同事类太多的话,中介者的代码会非常复杂,难以维护

ok,再来区分下中介者模式与观察模式。

观察者模式中:一个对象要么是观察者,要么是被观察者,交互关系有条理。

中介者模式中:只有在参与者的交互关系非常错综复杂的时候,才会考虑中介模式。此外中介模式相当于一个管理者,可以维护不同参与者的通知顺序的控制,功能会更强。

中介者模式实际使用的场景貌似不多,目的就是为了解耦,而上图的星型结构的转变更是中介模式解耦的思想体现。

还剩最后三种了。下回见~