php语言很灵活,正是由于灵活撑握起来没有固定规则和规范,所以学好PHP,深入理解设计模式还是有非常有必要。接下来要说的是设计模式中的观察者模式,php提供了一套观察者和被观察者接口,如下图。
The SplSubject interface 必须实现attach,detach,notify三个方法,还会用到SplOberver和SplObjectStorage,可以查阅PHP手册提前熟悉这两个抽象类的具体用法
案例:观察者模式实现:用户登入后通知安全检测帐号安全,然后再通知广告模块推荐广告具体实现思路如下,结合代码注释阅读
class Users implements SplSubject{
//定义登入次数,通
public $lognum;
//根据用户的爱好推荐广告
public $hobby;
protected $observers = null;
/**
*@desc 构造方法
*/
public function __construct($hobby){
$this->lognum = rand(1,10);//这里随机生成,具体项目可以从项目中取出登入次数
$this->hobby = $hobby;
$this->observers = new SplObjectStorage();
}
/**
* @desc 登入模块,这里省去了session操作的步骤
*/
public function login(){
//操作session省略
$this->notify();
}
/**
*@desc 抽象类SplSubject实现的attach,必须有
*/
public function attach(SplObserver $observer)
{
$this->observers->attach($observer);
}
/**
*@desc 抽象类SplSubject实现的detach,必须有
*/
public function detach(SplObserver $observer) {
$this->observers->detach($observer);
}
/**
*@desc 抽象类SplSubject实现的notify,必须有
*/
public function notify(){
$this->observers->rewind();
while($this->observers->valid()) {
$observer = $this->observers->current();
$observer->update($this);
$this->observers->next();
}
}
}
class secrity implements SplObserver{
public function update(SplSubject $subject){
if ($subject->lognum < 3){
echo '这是第'.$subject->lognum.'安全登入';
} else {
echo '这介第'.$subject->lognum.'异常登入';
}
}
}
class ad implements SplObserver{
public function update(SplSubject $subject){
if ($subject->hobby == 'sports') {
echo '运动会';
} else {
echo '好好学习,天天向上';
}
}
}
$user = new Users('sport');
$user->attach(new secrity());
$user->attach(new ad());
$user->login();
这里用观察者模式实现了登入后通知帐号安全模块校验,和通知广告模块,在很多项目中都会运用到这种思路,学习设计模式最重要的是学习编程的思维,然后灵活运用。
为了更好理解观察者模式,写一段代码实现PHP的内部通知机制,如当一个类的属性发生变化时,另外一个类就可以收到通知。查看下面示例
interface Observer{
function getInfo($info = '');
}
class Observer1 implements Observer{
public function getInfo($info = '')
{
var_dump($info);
}
}
abstract class EventGenerator
{
public $observers = [];
public function addObservers(observer $observer)
{
$this->observers[] = $observer;
}
public function notify($info = '')
{
foreach($this->observers as $observer) {
$observer->getInfo($info);
}
}
}
class Events extends EventGenerator{
private $info = 'init';
public function trigger($info = '')
{
echo "before:".$this->info."\r\n";
$this->info = $info;
echo "after:".var_dump($this->info)."\r\n";
$this->notify($info);
}
}
$event = new Events();
$obser = new Observer1();
$event->addObservers($obser);
$arr = array('one'=>'observer change');
$event->trigger($arr);
代码说明:当Events类的属性info发生改变时observer1类就收到了通知
总结:利用了PHP自带的方法实现了观察者模式和灵活运用面向对象编程实现了当一个类的属性发生变化时,另外一个类就可以收到通知