定义
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。
实现方式
有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。
<?php
abstract class Subject
{
private $observers = [];
public function attach(Observer $observer)
{
array_push($this->observers, $observer);
}
public function detatch($observer)
{
foreach ($this->observers as $key => $value) {
if ($observer === $value) {
unset($this->observers[$key]);
}
}
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update();
}
}
}
abstract class Observer
{
abstract function update();
}
class ConcreteSubject extends Subject
{
private $subjectState;
public function setState($state)
{
$this->subjectState = $state;
}
public function getState()
{
return $this->subjectState;
}
}
class ConcreteObserver extends Observer
{
private $name;
private $subject;
function __construct(ConcreteSubject $subject, $name)
{
$this->subject = $subject;
$this->name = $name;
}
public function update()
{
echo "观察者 ".$this->name."的新状态是:".$this->subject->getState()."\n";
}
}
$s = new ConcreteSubject();
$s->attach(new ConcreteObserver($s, "x"));
$s->attach(new ConcreteObserver($s, "y"));
$z = new ConcreteObserver($s, "z");
$s->attach($z);
$s->detatch($z);
$s->setState('ABC');
$s->notify();
应用场景
邮件订阅、RSS Feeds,状态机流转。
总结
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
观察者模式所做的工作其实就是在接触耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。