php设计模式(十八):中介者模式(Mediator)

2023-05-14 09:18:41 浏览数 (1)

中介者模式

中介者模式又称为:调解人、控制器、Intermediary、Controller、Mediator。中介者是一种为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。

问题

中介者模式其实就是一个中介,前面我们介绍了:命令模式,命令模式在两个类之间建立一个中间类来达到解耦,中介模式也相同,区别的是命令模式只能单向通信,而中介者能双向通信(类似于全双工)。

中介者模式非常常见,就如两人聊天,你和他说如何找富婆包养,而他却和你聊如何高效养猪,这么聊下去只能医院见,可想而知这个天很难聊下去。这时候你们就需要一个中间人进行双边翻译了,把你的爱好和他的爱好综合一下双向通信。

假设我们现在需要开发一个租房系统,租客只知道要租什么样的房子,房东知道自己有什么房子(软件开发中不能贴广告)。而这样必须要双双进行对话才能知道房子合不合适,那我是不是要在每个对象中进行交流呢?

解决方法

就如上例子可知,没有第三人的时候,这就高度耦合,没有人调解。增加第三人时你只要和第三人说喜欢的就行,传达交给第三人,这样便能直接交流并使其相互独立。租客和房东中增加一个中介,这样便能高效传达了~

结构

MediatorInterface:中介接口类;一般会暴露一个 send(发送对话) 方法; Mediator:中介具体类;用于 房东 和 租客 对话; Customer:中介客户抽象类;申明共同方法; Landlord、Tenant:具体的顾客类(房东、租客);包含自我业务逻辑的类。每个顾客都有一个指向中介的引用;

代码示例

中介接口

代码语言:javascript复制
/**
 * 中介接口
 */
interface  MediatorInterface
{
    /**
     * 中间撮合消息
     * @param string $message
     * @param Customer $customer
     * @return mixed
     * @author chendashengpc
     */
    public function send(string $message, Customer $customer);
}

中介具体类

代码语言:javascript复制
/**
 * 中介公司
 */
class Mediator implements MediatorInterface
{
    /**
     * 房东
     * @var Customer
     */
    public Customer $landlord;
    /**
     * 租客
     * @var Customer
     */
    public Customer $tenant;

    public function send(string $message, Customer $customer)
    {
        if ($this->landlord == $customer) {
            return $this->tenant->getMessage($message);
        }
        return $this->landlord->getMessage($message);
    }
}

顾客抽象类

代码语言:javascript复制
/**
 * 顾客抽象类
 */
abstract class Customer
{
    /**
     * 中介
     * @var MediatorInterface
     */
    protected MediatorInterface $mediator;

    /**
     * 顾客姓名
     * @var string
     */
    public string $name;

    public function __construct(string $name, MediatorInterface $mediator)
    {
        $this->name = $name;
        $this->mediator = $mediator;
    }

    /**
     * 获取对方信息
     * @param string $message
     * @return mixed
     * @author chendashengpc
     */
    abstract public function getMessage(string $message);

    /**
     * 和中介说
     * @param string $message
     * @return void
     * @author chendashengpc
     */
    public function declare(string $message)
    {
        return $this->mediator->send($message, $this);
    }
}

具体类

房东

代码语言:javascript复制
/**
 * 房东
 */
class Landlord extends Customer
{
    /**
     *
     * @return mixed|void
     * @author chendashengpc
     */
    public function getMessage(string $message)
    {
        return $this->name . '(房东) 获得对方消息:' . $message;
    }
}

租客

代码语言:javascript复制
/**
 * 租客
 */
class Tenant extends Customer
{
    /**
     *
     * @return mixed|void
     * @author chendashengpc
     */
    public function getMessage(string $message)
    {
        return $this->name . '(租客) 获得对方消息:' . $message;
    }
}

客户端使用

代码语言:javascript复制
/**
 * 初始化中介
 */
$intermediary = new Mediator();

$li = new Landlord('李先生', $intermediary);

$chen = new Tenant('陈大剩', $intermediary);

$intermediary->landlord = $li;
$intermediary->tenant = $chen;

echo $chen->declare('需要找一个带独卫的单间!') . PHP_EOL;

echo $li->declare('这刚好有一间带独立卫浴的房间') . PHP_EOL;

输出

代码语言:javascript复制
李先生(房东) 获得对方消息:需要找一个带独卫的单间!
陈大剩(租客) 获得对方消息:这刚好有一间带独立卫浴的房间

UML

优缺点

优点

  • 单一职责原则。可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。
  • 开闭原则。无需修改实际组件就能增加新的中介者。
  • 可以减轻应用中多个组件间的耦合情况。
  • 可以更方便地复用各个组件。

缺点

  • 一段时间后, 中介者可能会演化成为上帝对象。

与其他模式的关系

责任链、 命令、中介者和观察者用于处理请求发送者和接收者之间的不同连接方式:

  • 责任链按照顺序将请求动态传递给一系列的潜在接收者,直至其中一名接收者对请求进行处理。
  • 命令在发送者和请求者之间建立单向连接。
  • 中介者清除了发送者和请求者之间的直接连接,强制它们通过一个中介对象进行间接沟通。
  • 观察者允许接收者动态地订阅或取消接收请求。

0 人点赞