这一次,我们重新定义智慧互联网

微信号:foreverbestvip

详细了解

每一次尝试都代表着时代的进步

微信号:foreverbestvip

详细了解

这一刻,我们都是世界的佼佼者

微信号:foreverbestvip

详细了解

智慧互联网产品开发的领航者

微信号:foreverbestvip

详细了解

观察者模式(Observer)

免费 - Sunrise - - 浏览量: 0 - 文章来源

3.7.1. 目的

当对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。它使用的是低耦合的方式。

3.7.2. 例子

  • 使用观察者模式观察消息队列在 GUI 中的运行情况。

3.7.3. 注意

PHP 已经定义了2个接口用于快速实现观察者模式:SplObserver 和 SplSubject。

3.7.4. UML 图

3.7.5. 代码

你可以在 GitHub 查看这段代码。

User.php


<?php

namespace DesignPatterns\Behavioral\Observer;

/**
 * User 实现观察者模式 (称为主体),它维护一个观察者列表,
 * 当对象发生变化时通知  User。
 */
class User implements \SplSubject
{
    /**
 * @var string
 */
    private $email;

    /**
 * @var \SplObjectStorage
 */
    private $observers;

    public function __construct()
    {
        $this->observers = new \SplObjectStorage();
    }

    public function attach(\SplObserver $observer)
    {
        $this->observers->attach($observer);
    }

    public function detach(\SplObserver $observer)
    {
        $this->observers->detach($observer);
    }

    public function changeEmail(string $email)
    {
        $this->email = $email;
        $this->notify();
    }

    public function notify()
    {
        /** @var \SplObserver $observer */
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }
}

UserObserver.php


<?php

namespace DesignPatterns\Behavioral\Observer;

class UserObserver implements \SplObserver
{
    /**
 * @var User[]
 */
    private $changedUsers = [];

    /**
 * 它通常使用  SplSubject::notify()  通知主体
 *
 * @param \SplSubject $subject
 */
    public function update(\SplSubject $subject)
    {
        $this->changedUsers[] = clone $subject;
    }

    /**
 * @return User[]
 */
    public function getChangedUsers(): array
    {
        return $this->changedUsers;
    }
}

3.7.6. 测试

Tests/ObserverTest.php


<?php

namespace DesignPatterns\Behavioral\Observer\Tests;

use DesignPatterns\Behavioral\Observer\User;
use DesignPatterns\Behavioral\Observer\UserObserver;
use PHPUnit\Framework\TestCase;

class ObserverTest extends TestCase
{
    public function testChangeInUserLeadsToUserObserverBeingNotified()
    {
        $observer = new UserObserver();

        $user = new User();
        $user->attach($observer);

        $user->changeEmail('foo@bar.com');
        $this->assertCount(1, $observer->getChangedUsers());
    }
}

谈谈你的看法

请文明发言!