macfja/php-kvo

PHP 中的 KVO (键值观察) 设计模式

v0.1.0 2016-02-20 22:17 UTC

This package is auto-updated.

Last update: 2024-09-17 01:01:55 UTC


README

什么是 KVO   安装   用法   API

什么是 KVO ?

KVO (键值观察) 是一种设计模式,允许对象在属性发生变化时接收通知。
它允许你通过 Subject/Observer 设计模式,不创建硬链接,来保持对象之间的同步。
KVC (键值编码) 和 KVO (键值观察) 在 Cocoa 框架 (Objective-C) 中被广泛使用

安装

安装此库最简单的方式是使用 Composer

composer require macfja/php-kvo

用法

class Downloader extends AbstractObservable
{
  protected $progress;
  public function getProgress()
  {
    return $this->progress;
  }
  protected function receiveCallback($newProgress)
  {
    $this->setValueForKey('progress', $newProgress);
    // ... do something with the data
  }
  public function download()
  {
    // ... start the download
  }
}

class ProgressDisplay implements Listener
{
  public function observeValueForKeyPath($keyPath, $object, $change, &$context)
  {
    if ($keyPath == 'progress') {
      echo sprintf('Download in progress (%d%%)%s', $change[Observer::CHANGE_NEW], PHP_EOL);
    }
  }
}

$downloader = new Downloader();
$progress = new ProgressDisplay();
$downloader->addObserverForKey($progress, 'progress', Observer::OPTION_NEW|Observer::OPTION_INITIAL);
$downloader->download()

完整示例可以在目录 examples 中找到。

API

Observable 接口的 API

AbstractObservableProxy 中实现。
有一个用于快速实现的 trait:ObservableTrait

Observable::addObserverForKey 方法的 API

此方法允许您订阅键值变更通知。

Observable::addObserverForKey 选项列表。

  • Observer::OPTION_NEW,指示更改数组应提供新的属性值(如果适用)。

  • Observer::OPTION_OLD,指示更改数组应包含旧的属性值(如果适用)。

  • Observer::OPTION_INITIAL,如果指定,则在观察者注册方法返回之前,应立即向观察者发送通知。

    如果指定了 Observer::OPTION_NEW,通知中的更改数组将始终包含一个 Observer::CHANGE_NEW 条目,但将永远不会包含 Observer::CHANGE_OLDObserver::CHANGE_REQUESTED 条目。
    (在初始通知中,观察属性当前的值可能是旧的,但对于观察者来说是新的。)

  • Observer::OPTION_PRIOR,是否应在更改前后分别向观察者发送单独的通知,而不是更改后的单个通知。

    在更改之前发送的通知中的更改数组始终包含一个值为 trueObserver::CHANGE_PRIOR 条目,但永远不会包含 Observer::CHANGE_NEW 条目。当指定此选项时,更改后的通知中的更改数组包含的条目与未指定此选项时相同。您可以在观察者自己的键值观察合规性要求其在自己的属性上调用 willChangeValueForKey 方法,并且该属性的值取决于观察对象属性的值时使用此选项。

Observable::willChangeValueForKey 方法的 API

此方法触发所有已注册为具有 Observer::OPTION_PRIOR 选项的键的 Listener 的通知。
此方法应在键值更改之前调用。

Observable::didChangeValueForKey 方法的 API

此方法触发对所有未设置Observer::OPTION_PRIOR选项的注册了某个键的Listener的通知。
应该在键值改变后调用此方法。

Observer::setValueForKey方法的API

此方法更改键的值,并处理调用方法Observable::willChangeValueForKeyObservable::didChangeValueForKey

API,Observable::willChangeValueForKeyObservable::didChangeValueForKey的源值

  • Observer::SOURCE_SETTER,如果键的值是从一个setter方法更改的。(由Proxy类使用)
  • Observer::SOURCE_PROPERTY,如果键的值是从直接属性更改(公共类属性)更改的。(由Proxy类使用)
  • Observer::SOURCE_CUSTOM,如果值是在没有setter或从直接属性访问的情况下更改的。

注意:您可以使用自己的源类型,它只是一个字符串。

注意:如果Listener具有Observer::OPTION_INITIAL选项,则当注册时使用Observer::SOURCE_INITIAL,如果通知是在更改之前发送的

Listener接口的API

Listener::observeValueForKeyPath方法的API

每当观察到的键被修改时,都会调用此方法。

API,Listener::observeValueForKeyPath的更改数组

  • Observer::CHANGE_NEW,如果在注册观察者时指定了Observer::OPTION_NEW,则此键的值是属性的新的值。

  • Observer::CHANGE_OLD,如果在注册观察者时指定了Observer::OPTION_OLD,则此键的值是在属性更改之前的价值。

  • Observer::CHANGE_PRIOR,如果在注册观察者时指定了Observer::OPTION_PRIOR,则此通知是在更改之前发送的。

    更改数组包含一个Observer::CHANGE_PRIOR条目,如果通知是在更改之前发送的,则其值为true,如果通知是在更改之后发送的,则其值为false