PHP SPL模块中自带一个观察者模式,观察者模式是一个非常简单事件系统,包含两个或者更多交互的类,这个模式允许一个类观察另一个类的状态,当被观察的类发生变化的时候,这个模式会得到通知。
在观察者模式中,被观察的叫subject,而负责观察的类叫做observe,为了表达这些内容,SPL提供了SplSubject和SplObserver接口。
<?php
class car implements SplSubject
{
//车的类型
private $carName;
//车的状态,0为关闭,1这启动车子
private $carState = 0;
//初始化车的速度表值
private $carSpeed = 0;
//各项车的性能观察对象
private $Observers;
public function __construct($Name)
{
$this->carName = $Name;
$this->Observers = new SplObjectStorage;
}
//启动
public function start()
{
$this->carState = 1;
$this->notify();
}
//停车
public function stop()
{
$this->carState = 0;
$this->carSpeed = 0;
$this->notify();
}
//加速
public function accelerate($Acceleration)
{
if (0 === $this->carState) {
throw new Exception('先踩油门,不然车怎走啊!!!');
}
if (!is_int($Acceleration) || $Acceleration < 0) {
throw new Exception('加速值错了啊');
}
$this->carSpeed += $Acceleration;
$this->notify();
}
//增加监测对象
public function attach(SplObserver $observer)
{
if (!$this->Observers->contains($observer)) {
$this->Observers->attach($observer);
}
return true;
}
//删除监测对象
public function detach(SplObserver $observer)
{
if (!$this->Observers->contains($observer)) {
return false;
}
$this->Observers->detach($observer);
return true;
}
//传送对象
public function notify()
{
foreach ($this->Observers as $observer) {
$observer->update($this);
}
}
public function __get($Prop)
{
switch ($Prop) {
case 'STATE':
return $this->carState;
break;
case 'SPEED':
return $this->carSpeed;
break;
case 'NAME':
return $this->carName;
break;
default:
throw new Exception($Prop . 'cannotberead');
}
}
public function __set($Prop, $Val)
{
throw new Exception($Prop . 'cannotbeset');
}
}
class carStateObserver implements SplObserver
{
private $SubjectState;
public function update(SplSubject $subject)
{
switch ($subject->STATE) {
case 0:
if (is_null($this->SubjectState)) {
echo $subject->NAME . '没有启动呢' . "<br />";
} else {
echo $subject->NAME . '熄火了' . "<br />";
}
$this->SubjectState = 0;
break;
case 1:
if (1 !== $this->SubjectState) {
echo $subject->NAME . '启动了' . "<br />";
$this->SubjectState = 1;
}
break;
default:
throw new Exception('UnexpectederrorincarStateObserver::update()');
}
}
}
class carSpeedObserver implements SplObserver
{
public function update(SplSubject $subject)
{
if (0 !== $subject->STATE) {
echo $subject->NAME . '目前速度为' . $subject->SPEED . 'Kmh' . "<br />";
}
}
}
class carOverspeedObserver implements SplObserver
{
public function update(SplSubject $subject)
{
if ($subject->SPEED > 130) {
throw new Exception('加速限制在130以内,你违规了!' . "<br />");
}
}
}
try {
$driver = new car('AUDIA4');
$driverObserver1 = new carStateObserver;
$driverObserver2 = new carSpeedObserver;
$drivesrObserver3 = new carOverspeedObserver;
$driver->attach($driverObserver1);
$driver->attach($driverObserver2);
$driver->attach($drivesrObserver3);
$driver->start();
$driver->accelerate(10);
$driver->accelerate(30);
$driver->stop();
$driver->start();
$driver->accelerate(50);
$driver->accelerate(70);
$driver->accelerate(100);
$driver->accelerate(150);
} catch (Exception $e) {
echo $e->getMessage();
}
?>