1:观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
2:场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
3:观察者模式实现了低耦合,非侵入式的通知与更新机制。
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017/3/17
* Time: 16:59
*/
interface ObSubject {
/**
* 增加一个新的观察者对象
* @param Observer $observer
*/
public function attach(UserObserver $observer,$name);
/**
* 删除一个已注册过的观察者对象
* @param Observer $observer
*/
public function detach(UserObserver $observer,$name);
/**
* 通知所有注册过的观察者对象
*/
public function notifyObservers($name);
}
class CreateObSubject implements ObSubject
{
private static $_observers = [];
public function attach(UserObserver $observer, $name)
{
return self::$_observers[$name] = $observer;
}
public function detach(UserObserver $observer, $name)
{
$index = array_search($observer, self::$_observers);
if ($index === FALSE || ! array_key_exists($index, self::$_observers)) {
return FALSE;
}
unset(self::$_observers[$index]);
return TRUE;
}
public function notifyObservers($name = null,$options = [])
{
if (!is_array(self::$_observers)) {
return FALSE;
}
foreach (self::$_observers as $key => $observer) {
//可以单独提醒一个具体的角色,否则就全部提示
if($name)
{
if($key == $name)
{
$observer->update($name,$options);
}
}else{
$observer->update($name,$options);
}
}
return TRUE;
}
}
/**
* 抽象观察者角色
*/
interface UserObserver {
/**
* 更新方法
*/
public function update($name = null,$options = []);
}
class User implements UserObserver
{
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function update($name = null,$options = [])
{
var_dump($options);
echo get_called_class().' ->> The notice is:'.$name."\r\n";
}
}
class User01 implements UserObserver
{
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function update($name = null,$options = [])
{
var_dump($options);
echo get_called_class().' ->> The notice is:'.$name."\r\n";
}
}
$obj = new CreateObSubject();
$u = new User('gaoxx');
$u01 = new User01('gaoxx');
//添加一个新的角色
$obj->attach($u,'gaoxx');
//添加一个新的角色
$obj->attach($u01,'gaoxx01');
$obj->notifyObservers(null,['age' => 11,'name' => 'zdfjsdhfjsdhj']);
运行结果:
D:\myapache\www\demo\guancazhe\User.php:90:
array(2) {
'age' =>
int(11)
'name' =>
string(13) "zdfjsdhfjsdhj"
}
User ->> The notice is:
D:\myapache\www\demo\guancazhe\User.php:104:
array(2) {
'age' =>
int(11)
'name' =>
string(13) "zdfjsdhfjsdhj"
}
User01 ->> The notice is:
通知到了所有角色,并且传递对应的参数,对于负责的业务不仅可以精简代码,还可以大大使得模块之间的耦合性大大降低。