phine/observer

此包已被废弃,不再维护。未建议替代包。

一个实现了观察者模式的PHP库。

2.0.1 2013-12-17 23:50 UTC

This package is not auto-updated.

Last update: 2021-12-07 01:41:42 UTC


README

Build Status Coverage Status Latest Stable Version Total Downloads

一个实现了观察者模式的PHP库。

摘要

此库提供了观察者模式的一个实现。您可以使用它来创建其他库,例如事件管理器、状态机、MVC框架,甚至为应用提供插件系统。

要求

安装

通过 Composer

$ composer require "phine/observer=~2.0"

使用方法

要创建主题,您需要创建自己的 SubjectInterface 实现,或者使用捆绑的 Subject 类。

use Phine\Observer\Subject;

$subject = new Subject();

观察

然后您需要创建自己的 ObserverInterface 实现来观察对主题所做的更改。您可以使用多个观察者实现实例,甚至相同的实例多次。

use Phine\Observer\ObserverInterface;
use Phine\Observer\SubjectInterface;

// register a few instances
$subject->registerObserver(new Message('First'));
$subject->registerObserver(new Message('Second'));

// register the same one twice
$reuse = new Message('Third');

$subject->registerObserver($reuse);
$subject->registerObserver($reuse);

// notify all observers of an update
$subject->notifyObservers();

/**
 * Simply echos a message when updated.
 */
class Message implements ObserverInterface
{
    /**
     * The message to echo.
     *
     * @var string
     */
    private $message;

    /**
     * Sets the message to echo on update.
     *
     * @param string $message The message.
     */
    public function __construct($message)
    {
        $this->message = $message;
    }

    /**
     * {@inheritDoc}
     */
    public function receiveUpdate(SubjectInterface $subject)
    {
        echo $this->message, "\n";
    }
}

根据上面的例子,您可以期待以下输出

First
Second
Third
Third

优先级排序观察者

SubjectInterface 的实现支持在注册时对观察者进行优先级排序(registerObserver())。默认情况下,如所有示例所示,优先级为 SubjectInterface::FIRST_PRIORITY(即 0,零)。但是,您可以指定自己的优先级

$subject->registerObserver(new Message('A'), SubjectInterface::LAST_PRIORITY);
$subject->registerObserver(new Message('B'), 789);
$subject->registerObserver(new Message('C'), 123);
$subject->registerObserver(new Message('D'), 456);
$subject->registerObserver(new Message('E'), SubjectInterface::FIRST_PRIORITY);

根据上面的例子,您可以期待以下输出

E
C
D
B
A

当主题更新其观察者时,它从优先级 0(零)开始,逐级到 PHP_INT_MAX(最低可能的优先级)。如果使用相同提供者注册了多个观察者,它们将按注册顺序更新。

中断更新

当主题正在更新其注册的观察者时,观察者可以中断主题。观察者通过调用 SubjectInterface::interruptUpdate() 方法来执行中断。

use Phine\Observer\Exception\ReasonException;

/**
 * Simply interrupts the subject in the middle of an update.
 */
class InterruptingCow implements ObserverInterface
{
    /**
     * Interrupts the update.
     */
    public function receiveUpdate(SubjectInterface $subject)
    {
        // do some work

        $subject->interruptUpdate(
            new ReasonException('MOOOOO')
        );

        // do some final work
    }
}

使用以下示例

// create a new subject
$subject = new Subject();

// register some observers
$subject->registerObserver(new Message('So what did the interrupt cow say?'));
$subject->registerObserver(new InterruptingCow());
$subject->registerObserver(new Message('We never get this far.'));

// notify the observers
$subject->notifyObservers();

您可以期待以下输出

So what did the interrupting cow say?
PHP Fatal error:  Uncaught exception '[...]' with message 'MOOOOO' [...]
[...]

观察者不需要提供原因(ReasonException 实例),但如果提供了,将肯定有助于调试过程。

主题集合

有时您可能需要管理一组主题。此库提供了两种方法:CollectionArrayCollectionCollection 将单个主题与特定的唯一标识符关联。

use Phine\Observer\Collection;

// create a new collection
$collection = new Collection();

// register a few subjects
$collection->registerSubject('one', new Subject());
$collection->registerSubject('two', new Subject());
$collection->registerSubject('three', new Subject());

然后您可以按需检索或替换主题。

// replace one
$collection->registerSubject('two', new Subject());

// update observers of another
$collection->getSubject('three')->notifyObservers();

ArrayCollection 类提供了一种更简洁的方式来管理主题注册。它是 Collection 类的扩展,支持通过 ArrayCollectionInterface 进行数组访问。

use Phine\Observer\ArrayCollection;

// create a new collection
$collection = new ArrayCollection();

// register a few subjects
$collection['one'] = new Subject();
$collection['two'] = new Subject();
$collection['three'] = new Subject();

与常规的Collection类一样,您也可以替换和检索单个主题。

// replace one
$collection['two'] = new Subject();

// update observers of another
$collection['three']->notifyObservers();

文档

您可以在以下位置找到API文档

许可证

此库可在MIT许可证下使用。