设计模式 中介者模式

109 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 image.png

介绍

wiki:中介者模式定义了一个中介者对象,该对象封装了系统中对象间的交互方式。 由于它可以在运行时改变程序的行为,这种模式是一种行为型模式 。通常程序由大量的类组成,这些类中包含程序的逻辑和运算。 在中介者模式中,对象间的通信过程被封装在一个中介者(调解人)对象之中。 对象之间不再直接交互,而是通过调解人进行交互。 这么做可以减少可交互对象间的依赖,从而降低耦合。

角色

角色说明
Mediator抽象中介者
ConcreteMediator具体中介者
Colleague抽象同事类
ConcreteColleague具体同事类

角色示例

类名担任角色说明
ExpressMediator快递
SFExpressConcreteMediator顺丰快递
UserColleague用户
SenderConcreteColleague寄件人
ReceiverConcreteColleague收件人

UML类图

image.png

代码

<?php 
abstract class User
{
    protected $name;
    protected $express;

    function __construct($name)
    {
        $this->name = $name;
    }

    abstract public function sendExpress($receiver,$package);
    abstract public function receiveExpress($sender,$package);

    public function checkExpress(){
        if(!$this->express) exit("未设置快递公司");
    }

    public function setExpress($express){
        $this->express = $express;
    }
}

class Sender extends User
{
    public function sendExpress($receiver,$package)
    {
        $this->checkExpress();
        $this->express->ship($receiver,$package);
        return "我是".$this->name.",寄".$package."给".$receiver->name.PHP_EOL;
    }

    public function receiveExpress($sender,$package)
    {
        return "我是".$this->name.",收到".$sender->name."的".$package.PHP_EOL;
    }
}

class Receiver extends User
{
    public function sendExpress($receiver,$package)
    {
        $this->checkExpress();
        $this->express->ship($receiver,$package);
        return "我是".$this->name.",寄".$package."给".$receiver->name.PHP_EOL;
    }

    public function receiveExpress($sender,$package)
    {
        return "我是".$this->name.",收到".$sender->name."的".$package.PHP_EOL;
    }
}

abstract class Express
{
    abstract public function ship($user,$package);
    abstract public function fillForm($user);
}

class SFExpress extends Express
{
    protected static $nameList;
    function __construct()
    {
        if (!isset(self::$nameList)) {
            self::$nameList = [];
        }
    }

    public function ship($user,$package)
    {
        if(count(self::$nameList) < 2) {
            exit("请核对快递单中的寄件或收件人是否填写");
        }
        return $user->receiveExpress($user, $package);
    }

    public function fillForm($user)
    {
        if (!in_array($user, self::$nameList)) {
            self::$nameList[get_class($user)] = $user;
        }
        $user->setExpress($this);
    }
}

$sender = new Sender("小哀");
$receiver = new Receiver("柯南");

$sfEpress = new SFExpress();
$sfEpress->fillForm($sender);
$sfEpress->fillForm($receiver);

echo $sender->sendExpress($receiver, "APTX-4869的解药");
echo $receiver->sendExpress($sender, "感谢信");

创建 Test.php,内容如上。

执行

$ php Test.php
我是小哀,寄APTX-4869的解药给柯南
我是柯南,寄感谢信给小哀