`
lanlansnss
  • 浏览: 45414 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

设计模式-观察者模式

    博客分类:
  • php
 
阅读更多
<?php
/**
 * 观察者模式
 * 实现用户登录 并且 记录下log 发送mail如果ip在匹配iplist设置cookie
 * 
 */

interface Observable{
		function attach( Observer $observer );
		function detach( Observer $observer );
		function notify();
}

class Login implements  Observable {
	private $observers = array();
	const LOGIN_USER_UNKNOW = 1;
	const LOGIN_WRONG_PASS  = 2;
	const LOGIN_ACESS       = 3;
	private $status   = array();
	function attach( Observer $observer ){
		$this->observers[] = $observer;
	}
	function detach( Observer $observer ){
		$newobservers = array();
		foreach ( $this->observers as $obs ){
			if( $obs !== $observer){
				$newobservers[] = $obs;
			}
		}
		$this->observers = $newobservers;
	} 
	function notify(){
		foreach ( $this->observers as $obs ){
			$obs->update( $this );
		}
	}
	/**
	 * 登录启动器
	 * 记录登录状态
	 * return BOOLEAN
	 * 
	 * */
	function handleLogin( $user, $pass, $ip ){
		switch ( rand(1,3) ) {
			case 1:
				$this->setStatus( self::LOGIN_ACESS , $user, $ip );
				$ret = TRUE;
				break;
			case 2:
				$this->setStatus( self::LOGIN_WRONG_PASS, $user, $ip );
				$ret = FALSE;
				break;
			case 3:
				$this->setStatus( self::LOGIN_USER_UNKNOW, $user, $ip );
				$ret = FALSE;
				break;
		}
		$this->notify();
		return $ret;
	}
	/**
	 * 记录登录状态
	 *
	 * @param unknown_type $status
	 * @param unknown_type $user
	 * @param unknown_type $ip
	 */
	private function setStatus( $status, $user, $ip ){
		$this->status = array( $status, $user, $ip );
	}
	/**
	 * 获得登录状态
	 *
	 * @return unknown
	 */
	function getStatus(){
		return $this->status;
	}
}
/*定义Observer*/
interface Observer{
	function update( Observable $observable );
}
abstract class LoginObserver implements Observer {
	private $login;
	function __construct( Login $login ) {
		$this->login = $login;
		$login->attach( $this );
	}
	function update( Observable $observable ){
		if( $observable === $this->login ){
			$this->doUpdate( $observable );
		}
	}
	abstract function  doUpdate( Login $login );
}
/**
 * 登录错误发邮件通知用户
 *
 */
class SecurityMonitor extends LoginObserver {
	function doUpdate ( Login $login  ){
		$status = $login->getStatus();
		if( $status[0] === LOGIN::LOGIN_WRONG_PASS ){
			print __CLASS__."\tsend mail to sysadmin\n";
		}
	}
}
/**
 *记录log日志
 *
 */
class GeneralLogger extends LoginObserver {
	function doUpdate( Login $login ){
		$status = $login->getStatus();
		print __CALSS__.":\t add login data to log\n";
	}
}
/**
 * 登录ip匹配iplist
 * 设置cookie
 *
 */
class PartnershipTool extends LoginObserver {
	function doUpdate( Login $login ){
		$status = $login->getStatus();
		print __CLASS__.":\t set cookie of ip match alist \n";
	}
}
$login = new Login();
new SecurityMonitor( $login );
new GeneralLogger( $login );
new PartnershipTool( $login );

$login->handleLogin('snuser','s','s');


php可以通过内置的Spl(standard php library php标准类)提供观察者模式的原生支持。
SPl是一套可以帮助程序员处理很多面向对象的工具
其中观察者(obServer)由三个元素组成:SplObserver , SplSubject , SplObjectStrorage
其中SploOserver和SplSubject都是接口和上面所说的Observer 和 Observable接口完全相同
SplObjectStorage是一个工具类, 用于处理存储对象和删除对象。

下面就是改进后的示例代码
<?php
/**
 * 使用php内部的对象工具,
 * 完成观察者模式
 * SplObserver
 * SplSubject
 * SplObjectStorage工具类用于存储对象和删除对象
 * 实现用户登录 并且 记录下log 发送mail如果ip在匹配iplist设置cookie
 * 
 */

class Login implements SplSubject {
	private $storage;
	const LOGIN_USER_UNKNOW = 1;
	const LOGIN_WRONG_PASS  = 2;
	const LOGIN_ACESS       = 3;
	private $status   = array();
	function __construct(){
		$this->storage = new SplObjectStorage();
	}
	function attach( SplObserver $observer ){
		$this->storage->attach( $observer );
	}
	function detach( SplObserver $observer ){
		$this->storage->detach($observer);
	}
	function notify(){
		foreach ( $this->storage as $obs ){
			$obs->update( $this );
		}
	}
		/**
	 * 登录启动器
	 * 记录登录状态
	 * return BOOLEAN
	 * 
	 * */
	function handleLogin( $user, $pass, $ip ){
		switch ( rand(1,3) ) {
			case 1:
				$this->setStatus( self::LOGIN_ACESS , $user, $ip );
				$ret = TRUE;
				break;
			case 2:
				$this->setStatus( self::LOGIN_WRONG_PASS, $user, $ip );
				$ret = FALSE;
				break;
			case 3:
				$this->setStatus( self::LOGIN_USER_UNKNOW, $user, $ip );
				$ret = FALSE;
				break;
		}
		$this->notify();
		return $ret;
	}
	/**
	 * 记录登录状态
	 *
	 * @param unknown_type $status
	 * @param unknown_type $user
	 * @param unknown_type $ip
	 */
	private function setStatus( $status, $user, $ip ){
		$this->status = array( $status, $user, $ip );
	}
	/**
	 * 获得登录状态
	 *
	 * @return unknown
	 */
	function getStatus(){
		return $this->status;
	}
	
}
abstract class LoginObserver implements SplObserver {
	private $login;
	function __construct( Login $login ){
		$this->login = $login;
		$login->attach( $this );
	}
	function update( SplSubject $subject ){
		if( $subject === $this->login ){
			$this->doUpdate( $subject );
		}
	}
	abstract function doUpdate( Login $login );
}
/**
 * 登录错误发邮件通知用户
 *
 */
class SecurityMonitor extends LoginObserver {
	function doUpdate ( Login $login  ){
		$status = $login->getStatus();
		if( $status[0] === LOGIN::LOGIN_WRONG_PASS ){
			print __CLASS__."\tsend mail to sysadmin\n";
		}
	}
}
/**
 *记录log日志
 *
 */
class GeneralLogger extends LoginObserver {
	function doUpdate( Login $login ){
		$status = $login->getStatus();
		print __CALSS__.":\t add login data to log\n";
	}
}
/**
 * 登录ip匹配iplist
 * 设置cookie
 *
 */
class PartnershipTool extends LoginObserver {
	function doUpdate( Login $login ){
		$status = $login->getStatus();
		print __CLASS__.":\t set cookie of ip match alist \n";
	}
}
$login = new Login();
new SecurityMonitor( $login );
new GeneralLogger( $login );
new PartnershipTool( $login );
$login->detach(new PartnershipTool( $login ));
$login->handleLogin('user','s','s');



引用文章http://blog.csdn.net/swengineer/article/details/6268244

是一个观察者模式的案例。
/**
 * 观察者模式应用场景实例
 *
 * 免责声明:本文只是以哈票网举例,示例中并未涉及哈票网任何业务代码,全部原创,如有雷同,纯属巧合。
 *
 * 场景描述:
 * 哈票以购票为核心业务(此模式不限于该业务),但围绕购票会产生不同的其他逻辑,如:
 * 1、购票后记录文本日志
 * 2、购票后记录数据库日志
 * 3、购票后发送短信
 * 4、购票送抵扣卷、兑换卷、积分
 * 5、其他各类活动等
 *
 * 传统解决方案:
 * 在购票逻辑等类内部增加相关代码,完成各种逻辑。
 *
 * 存在问题:
 * 1、一旦某个业务逻辑发生改变,如购票业务中增加其他业务逻辑,需要修改购票核心文件、甚至购票流程。
 * 2、日积月累后,文件冗长,导致后续维护困难。
 *
 * 存在问题原因主要是程序的"紧密耦合",使用观察模式将目前的业务逻辑优化成"松耦合",达到易维护、易修改的目的,
 * 同时也符合面向接口编程的思想。
 *
 * 观察者模式典型实现方式:
 * 1、定义2个接口:观察者(通知)接口、被观察者(主题)接口
 * 2、定义2个类,观察者对象实现观察者接口、主题类实现被观者接口
 * 3、主题类注册自己需要通知的观察者
 * 4、主题类某个业务逻辑发生时通知观察者对象,每个观察者执行自己的业务逻辑。
 *
 * 示例:如以下代码
 *
 */

/**
 * *
 * 买票
 * 记录购买信息
 * 送优惠卷
 * 短信日志记录
 * 文本日志
 * 
 */
由于原文是使用JAVA来实现 , 下面我用phpSPL工具 来实现观察者模式 实现这个案例
/**
 * 构建主题, 用于发送通知
 * 
 * 
 * */
class buyTicket implements SplSubject  {
	private $ticket;
	private $storage;
	function __construct (){
		$this->storage = new SplObjectStorage();
	}
	function attach( SplObserver $object ){
		$this->storage->attach($object);
	}
	function detach( SplObserver $object ){
		$this->storage->detach($object);
	}
	function notify(){
		foreach ( $this->storage as $obs ){
			$obs->update( $this );
		}
	}
	/**
	 * 买票成功 
	 * 发送通知记录日志
	 * 送折扣劵
	 *
	 * @return buyTicket
	 */
	function buyTicket(){
		$this->ticket = 'NO.12, $100.';
		$this->notify();
	}
	function getTicket(){
		return $this->ticket;
	}
}
/**
 * 接收通知的观察者
 * 判断通知来源, 并且相应观察者执行相应的操作
 *
 */
abstract class  ticketObject implements SplObserver {
	private $buyTicket;
	function __construct( buyTicket $buyTicket ){
		$this->buyTicket = $buyTicket;
		$buyTicket->attach( $this );
	}
	function update( SplSubject $subject ) {
		if( $subject === $this->buyTicket ){
			$this->doUpdate( $subject );
		}
	}
	abstract  function doUpdate( SplSubject $buyTicket );
}
/**
 * 
 * 日志观察者接到通知记录日志
 *
 */
class ticketLogger  extends  ticketObject {
	function doUpdate( SplSubject $buyTicket ){
		print __CLASS__.' 日志计入 买票 '.$buyTicket->getTicket()."\n";
	}
	
}
/**
 * 
 * 折扣劵观察者 接到通知发送折扣劵
 *
 */
class ticketDid  extends ticketObject {
	function doUpdate( SplSubject $buyTicket ){
		print __CLASS__."\t 送10元折扣卷一张".$buyTicket->getTicket();
	}
}
$ticket = new buyTicket();
new ticketLogger( $ticket );
new ticketDid( $ticket );
$ticket->buyTicket();

分享到:
评论

相关推荐

    跟我一起学 设计模式-观察者模式

    观察者模式,也称为发布-订阅模式或事件驱动模式,是一种行为设计模式,它定义了对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 在C#、ASP.NET等.NET框架中,...

    设计模式-观察者模式.ppt

    观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象事件发生时通知多个“观察”该对象的其他对象。这个模式的核心在于建立一种一对多的关系,当一个对象的状态改变时,所有依赖于它的对象都会得到...

    设计模式-观察者模式-作业-observer.zip

    观察者模式(Observer Pattern)是软件设计模式中的行为模式之一,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动或发布-...

    设计模式-观察者模式(讲解及其实现代码)

    总结来说,观察者模式是一种重要的设计模式,它允许对象在状态改变时自动通知其他对象,从而降低了系统各部分之间的耦合度,提高了代码的灵活性和可扩展性。在实际项目中,正确使用观察者模式可以有效地管理组件间的...

    Java 设计模式-观察者模式(Observer)

    结合微信公众号讲解观察者模式,生动形象,关键是上手快啊

    java常用设计模式-观察者模式

    观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。该模式适用于需要在对象间建立动态的、松散耦合的关系的...

    设计模式-观察者模式(读书笔记)

    观察者模式是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这个模式在很多场景下都有广泛的应用,例如事件处理、...

    设计模式-观察者模式 基于MFC实现的消息监听机制

    基于MFC实现的消息监听机制,利用了设计模式中的观察者模式,对线程间的同步做了优化,以及可以选择消息的发送类型:同步或异步发送。对于监听者而言在注册监听的同时可以选择监听的消息类型,避免了发送者发送的...

    JAVA-设计模式-行为型模式-观察者模式

    JAVA-设计模式-行为型模式-观察者模式

    设计模式--观察者模式java例子

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    Android设计模式--观察者模式DEMO

    Android设计模式--观察者模式DEMO 观察者模式是一个使用频率非常高的模式,他最常用的地方是GUI系统和订阅-发布系统。 该模式的最重要的作用就是解耦,使观察者和被观察者之间依赖尽可能小,甚至好无依赖。

    设计模式-观察者

    观察者模式(Observer Pattern)是行为设计模式的一种,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心思想是发布-订阅模型,其中...

    java设计模式-观察者模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...

    C++设计模式--观察者模式 demo

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它在C++中的应用广泛且实用。这种模式的核心思想是“主体”(Subject)与“观察者”(Observer)之间的松耦合关系,允许一个对象(即主体)的状态...

    c++设计模式-行为型模式-观察者模式

    c++设计模式-行为型模式-观察者模式;qt工程;c++简单源码; 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式...

    设计模式之观察者模式Java实现

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    设计模式--观察者 c++版本

    观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心思想是主体(Subject)与观察者(Observer)之间的...

    java设计模式-观察者 小案例

    观察者模式(Observer Pattern)是其中一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 在Java中,观察者模式通常通过`java.util....

Global site tag (gtag.js) - Google Analytics