Joomla设计模式-观察者模式

知道joomla的人都清楚Joomla的插件机制是观察者模式实现的。那么究竟什么是观察者模式呢?如何用代码来实现观察者模式呢?

观察者模式有两个概念。一个是主题。一个是观察者。举一个例子来说明这两个概念。

你向一个报社订了一份报纸,隔壁的张三也想报社订了一份报纸。然后每天你都会收到该报社送来的报纸。当然隔壁的张三能会收到。在这期间,只要他们已有报纸都会主动送来,除非你打电话去取消订阅。

在这个事情中,报社的就是主题。而你和张三就是两个观察者。因为你们订阅了报纸(向主题注册了),报社就会自动送报纸给你(当主题有内容更新的时候就会通知观察者)。

通过上面的过程,我们可以看见,其实观察者模式解决的是对象之间的一对多的依赖。当一个对象改变状态的时候,其他依赖者都会收到通知。

在joomla中,只输出一个页面的过程中,会触发很多事件,比喻说加载内容完成。当这些事件触发的时候,系统就会自动调用关注这一事件的观察者们。(你可以修改文章内容)。

那么如何用PHP来实现观察者模式呢?

对如一个主题,他应该实现至少3个方法,一个观察者至少要实现一个方法。

 

	interface  subject 
	{
		public	function registerObserver( observer $o); //注册为观察者
		public	function removeObserver( observer $o);  //删除观察者
		public	function notifyObservers();  //通知观察者
	}
	
	interface observer
	{
		public	function update(); //更新
	}

 上面代码中定义了主题和观察者接口。我们的自己写的主题只需要实现subject接口即可。观察者只需实现observer接口。

如果我们要实现一个文章内容变化的主题,那么我们可以这样写代码:

class contentSubject implements subject
	{
		private $observers=array();//用于记录所有观察者的变量
		public function contentSubject()
		{
			echo "subject ok<br />";
		}
		
		public function registerObserver(observer $o)
		{
			array_push($this->observers ,$o); //将观察者放到数组中
		}
		
		public function removeObserver( observer $o)
		{
			unset( $this->observers[array_search($o,$this->observers) ]);//删除一个观察者
		}
		
		public function notifyObservers() //通知所有的观察者
		{
			foreach ($this->observers as $observer)
			{
				$observer->update();
			}
		}
	}

 上面的就基本实现了一个主题。我们用数组来作为观察者的容器。下面就是实现观察者了。

	class zmaxObserver implements observer
	{
		private $subject = null; //subject
		
		public function zmaxObserver(contentsubject $contentSubject)
		{
			$this->subject = $contentSubject;
						   
			$contentSubject->registerObserver($this);
			
		}
		public function update()
		{
			echo "ZMAX I am update<br />";
		}
	}
	class ztestObserver implements observer
	{
		private $subject = null; //subject
		public function ztestObserver(contentSubject $contentSubject)
		{
			$this->subject = $contentSubject;
			$this->subject->registerObserver($this);
		}
		public function update()
		{
			echo "ZTest I am update<br />";
		}
	}

 //上面实现了两个观察者。非常的简单。在构造观察者 时候需要指定一个需要观察的主题,并且向主题注册。这样我们基本上就能够做到和主题解偶,并且又能从主题获得数据。的确是一个非常不错的模式。

下面是测试该模式的代码:

echo "Test for overser pattern!<br />";
 $sub = new contentSubject();
 $objZmax = new zmaxObserver($sub);
 $objZtest = new ZtestObserver($sub);
 $sub->notifyObservers();
 $sub->removeObserver($objZmax);
 $sub->notifyObservers();

 感觉非常的不错。如果我们再用一种机制将观察者和主题分开为不同的文件。那么就可以实现出joomla的插件机制了。

 

 

 

 


收藏
0个人 收藏