感觉symfony中使用的service机制,依赖注入机制不是被很好的理解,主要是设计模式不了解,于是网上看了一下观察者模式的说明,算是有些了解了。
所谓观察者模式,就是当前对象应当有一个或者若干个观察者,当自己被改变时会通知观察者,让观察者做出反应,如果不用观察者模式,这个“做出反应”可能就是自己去实现的,这样使得代码耦合性太高,把这个反应放入到观察者,让观察者做自己的处理,当前类只专注于自己的业务处理,能有效降低耦合度。
还好PHP自带SPL,standard PHP library,其中就有观察者模式需要用到的接口SplSubject, SplObserver,下面介绍这两个接口。
SplSubject的定义,需要应用观察者模式的类必须实现此接口
SplSubject {
/* attach用于添加观察者,参数为SplObserver 对象 */
abstract public void attach ( SplObserver $observer )
/* attach用于接触观察者,参数为SplObserver 对象 */
abstract public void detach ( SplObserver $observer )
/* 用于向观察者发送通知 */
abstract public void notify ( void )
}
SplObserver 的定义,观察者接口
SplObserver {
/* SplSubject被修改时需要执行的操作 */
abstract public void update ( SplSubject $subject )
}
下面是示例代码:
class User implements \SplSubject
{
protected $data = array();
protected $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()
{
/** @var \SplObserver $observer 这里不一定要通知所有的观察者 */
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function __set($name, $value)
{
$this->data[$name] = $value;
// 通知观察者用户被改变
$this->notify();
}
}
简单解释:User类实现了SplSubject接口,并且实现了约定的attach,detach,notify三个方法,然后User类中有一个__set()
魔术方法,当通过魔术方法给兑现添加属性时会通知User的观察者,观察者于是会执行update方法,上面的类中attach,detach两个方法比较特别,因为他们的参数是一个对象,这个对象其实就是我们说的观察者,下面看看这个观察者是如何定义的:
class UserObserver implements \SplObserver
{
/**
* 观察者要实现的唯一方法
* 也是被 Subject 调用的方法
*
* @param \SplSubject $subject
*/
public function update(\SplSubject $subject)
{
echo get_class($subject) . ' has been updated';
}
}
这个观察者有一个upate方法,是实现的SqlObserver中的update方法,现在观察者模式就搭建好了,下面开始用这个观察者模式搭建起来的结构:
$user = new User();
$user->attach(new UserObserver );
$user->name = 'jake';
以上实现一个User对象,并添加一个观察者,然后给他赋值会执行set
方法,set
方法通知自己的观察者,观察者通过update做出了反应。