最近写代码乏力,所以打算好好学习一下设计模式,本文当作是一个笔记了。 PHP内部提供了SplObserver、SplSubject和SplObjectStorage这三个接口,利用这些接口可以很方便的构建PHP观察者模式。
//使用SPL实现观察者模式
<?php
class Order implements SplSubject {
private $observers;
private $uid;
private $goods_id;
public function __construct($uid, $goods_id)
{
$this->uid = $uid;
$this->goods_id = $goods_id;
$this->observers = new SplObjectStorage();
}
public function attach(SplObserver $observer)
{
$this->observers->attach($observer);
}
public function detach(SplObserver $observer)
{
$this->observers->detach($observer);
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function order()
{
echo "make order ok...".PHP_EOL;
echo '用户'.$this->uid.' 购买商品 '.$this->goods_id;
$this->notify();
}
public function getUid()
{
return $this->uid;
}
}
class SmsUser implements SplObserver {
// private $uid;
// private $content;
// public function __construct($uid, $content)
// {
// $this->uid = $uid;
// $this->content = $content;
// }
public function update(SplSubject $subject)
{
// var_dump(get_class($subject));
$uid = $subject->getUid();
echo "sending sms ...".PHP_EOL;
echo "给用户".$uid.'发送短信内容'.PHP_EOL;
}
}
class LogUser implements SplObserver {
public function update(SplSubject $subject)
{
echo "loging....".PHP_EOL;
}
}
$order = new Order('2849749330', 111);
$order->attach(new SmsUser());
$order->attach(new LogUser());
$order->order();
定义了一个订单类,下单后需要发送短信和LOG。
除了使用PHP 内置SPL接口实现观察者模式,还可以使用非SPL方式实现。 Subject参与者是一个抽象类而不是一个接口
用数组代替SplObjectStorage对象
abstract class Subject
{
protected $observers = [];
protected $stateNow;
public function attachObserver(Observer $observer)
{
array_push($this->observers, $observer);
}
public function detachObserver(Observer $observer)
{
$position = 0;
foreach ($this->observers as $viewer) {
++$position;
if($observer == $viewer) {
array_slice($this->observers, $position, 1);
}
}
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
class Order extends Subject
{
protected $uid;
protected $goods_id;
public function __construct($uid, $goods_id)
{
$this->uid = $uid;
$this->goods_id = $goods_id;
}
public function setState($stateSet)
{
$this->stateNow = $stateSet;
$this->notify();
}
public function getState()
{
return $this->stateNow;
}
public function getUid()
{
return $this->uid;
}
public function makeOrder()
{
echo "make order ok...".PHP_EOL;
echo '用户'.$this->uid.' 购买商品 '.$this->goods_id;
$this->notify();
}
}
interface Observer
{
function update(Subject $subject);
}
class SmsUser implements Observer {
public function update(Subject $subject)
{
$uid = $subject->getUid();
echo "sending sms ...".PHP_EOL;
echo "给用户".$uid.'发送短信内容'.PHP_EOL;
}
}
class LogUser implements Observer {
public function update(Subject $subject)
{
echo "loging....".PHP_EOL;
}
}
$order = new Order('2849749330', 111);
$order->attachObserver(new SmsUser());
$order->attachObserver(new LogUser());
$order->makeOrder();
exit();