Observer - 观察者模式

观察者模式:

<?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();


另外,PHP通过内置的SPL扩展,提供了对观察者模式的原生支持。SPL是一套可以帮助PHP程序员处理很多面向对象问题的工具,堪称是一把面向对象的瑞士军刀。

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();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值