观察者模式:
<?php
interface Subject
{
public function notify();
public function attach(Observer $observer);
public function detach(Observer $observer);
}
class LoginSubject implements Subject
{
private static $observers = array();
public function attach(Observer $observer)
{
if (!array_search($observer, self::$observers)) {
self::$observers[] = $observer;
}
}
public function detach(Observer $observer)
{
foreach (self::$observers as $obs) {
if ($obs != $observer) {
$newObservers[] = $obs;
}
}
self::$observers = $newObservers;
}
public function notify()
{
foreach (self::$observers as $obs) {
$obs->update($this);
}
}
public function login()
{
// 处理登录,设置登录状态
// setStatus();
}
// 返回登录状态信息
public function getStatus()
{
switch(rand(1,3)) {
case 1:
$status = array('200', 'vboy1', '127.0.0.1');
break;
case 2:
$status = array('400', 'vboy2', '127.0.0.2');
break;
case 3:
$status = array('500', 'vboy3', '127.0.0.3');
break;
}
return $status;
}
}
interface Observer
{
public function update(Subject $subject);
}
abstract class LoginObserver implements Observer
{
private $_login;
public function __construct(LoginSubject $loginSubject)
{
$this->_login = $loginSubject;
$loginSubject->attach($this);
}
public function update(Subject $subject)
{
if ($subject === $this->_login) { // 保证调用update函数的对象是LoginSubject类型
$this->doUpdate($subject);
}
}
abstract public function doUpdate(LoginSubject $loginSubject);
}
class log extends LoginObserver
{
public function doUpdate(LoginSubject $loginSubject)
{
$status = $loginSubject->getStatus();
if ($status[0] == '200') {
// Logger::successLogin(); // 记录登录日志
}
}
}
class mail extends LoginObserver
{
public function doUpdate(LoginSubject $loginSubject)
{
$status = $loginSubject->getStatus();
if ($status[0] == '400') {
// Mailer::send(); // 发邮件通知管理员
}
}
}
$loginSubject = new LoginSubject();
new log($loginSubject);
new mail($loginSubject);
$loginSubject->notify();
SplObjectStorage是一个工具类,用于更好的存储对象和删除对象。
如下所示:
<?php
class Login implements SplSubject
{
private $_observers;
public function __construct()
{
$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 $obs) {
$obs->update($this);
}
}
public function getStatus()
{
switch(rand(1,3)) {
case 1:
$res = 1;break;
case 2:
$res = 2;break;
case 3:
$res = 3;break;
}
return $res;
}
}
abstract class LoginObserver implements SplObserver
{
private $login;
public function __construct(Login $login)
{
$this->_login = $login;
$login->attach($this);
}
public function update(SplSubject $subject)
{
if ($subject === $this->_login) {
$this->doUpdate($subject);
}
}
abstract function doUpdate(Login $login);
}
class log extends LoginObserver
{
public function doUpdate(Login $login)
{
echo __CLASS__ . ':' . $login->getStatus() . ' ';
//Logger::login();
}
}
class mail extends LoginObserver
{
public function doUpdate(Login $login)
{
echo __CLASS__ . ':' . $login->getStatus() . ' ';
//Mailer::login();
}
}
$login = new Login();
new log($login);
new mail($login);
$login->notify();