yii中的事件理解

先来看个例子:

class Video {
    public function new(){
        $checkNewVideo = Video::find()->where("xxxxx")->one();
        if($checkNewVideo){
            //    通知各位
            LaoWang::newVideo();
            XiaoLi::newVideo();
            ChuanPu::newVideo();
            .......
            //    还有很多很多,比如在给某个集体客户群发、短信发等等等等
        }
    }
}

//    具体实现
$model = new Video();
$model->new()

其实,在系统小的时候,这是非常快捷有效的方式。

但是,当系统变大的时候,这种方法马上面临难以扩展的问题,并且容易出错。

这两个对象的耦合度太高了。

我们先改进上面的代码,观察者模式

/**
 * 被观察者接口
 * 定义了一些公用方法声明,使用观察者模式的类都可以继承此接口
 */
interface Observable {
    // 添加/注册观察者
    public function attach(Observer $observer);
    // 删除观察者
    public function detach(Observer $observer);
    // 触发通知
    public function notify();
}

class Video implements Observable {
    public $observers = [];//    订阅者

    //    添加观察者
    public function attach(Observer $observer){
        $key = array_search($observer, $this->observers);
        if ($key === false) {
            $this->observers[] = $observer;
        }
    }

    //    删除观察者
    public function detach(Observer $observer){
        $key = array_search($observer, $this->observers);
        if ($key !== false) {
            unset($this->observers[$key]);
        }
    }

    //    通知所有观察者
    public function notify(){
        foreach ($this->observers as $observer) {
            // 把本类对象传给观察者
            $observer->update($this);
        }
    }

    public function  new(){
        $checkNewVideo = Video::find()->where("xxxxx")->one();
        if($checkNewVideo){
            $this->notify();
        }
    }
}

你看到了,修改后的代码并不关心具体发送给谁,它只是遍历了所有观察者的列表,然后告诉他们一下而已,观察者增减对此类不会有任何影响。

对于观察者,数字不定,随时有增减,因此我们定义了一个观察者接口开始抽象它们。

/**
 * 观察者接口
 */
interface Observer
{
    // 接收到通知的处理方法
    public function update(Observable $observable);
}
class LaoWang implements Observer {
    public function update(Observable $observable){
        echo "立刻开始看视频";
    }
}

class XiaoMing implements Observer {
    public function update(Observable $observable){
        echo "收到后忽略通知";
    }
}

class ChuanPu implements Observer {
    public function update(Observable $observable){
        echo "收藏了一下,然后去wc看";
    }
}

class BingBing implements Observer {
    public function update(Observable $observable){
        echo "立刻开始看视频";
    }
}

$model = new Video();
$model->attach(new LaoWang());
$model->attach(new XiaoLi());
$model->attach(new ChuanPu());
$model->attach(new BingBing());
$model->new();

上面就是观察者模式,我们先预想一下我们的事件,假设我们定义了很多观察者代码,他们监听事件的发生,当一个事件被触发,这些观察者都会知道,执行各自的逻辑。

事件就是观察者模式的一种应用。

监听系统的某一个行为,实时获取并执行自己负责的代码。


yii事件案例:

  • 本地留一个log
  • 告诉登陆者的朋友它登陆了
  • 发送一个邮件给管理员

class UserController extends Controller {
	
	public function actionIndex(){
		// 这里有一些代码.....
		Yii::$app->user->login($user);
		//	todo 登陆后要做的事情				
	}
}

// OLog   app\models\OLog.php
class OLog {
	static public function add($event){
		echo "我记录了一条登陆记录";
	}
}
// Admin app\models\Admin.php
class Admin {
	static public function sendMail($event){
		echo "我给管理员发了邮件";
	}
}
// User app\models\User.php
class User {
	static public function notifyFirend($event){
		echo "告诉了朋友们我登陆了";
	}
}

class UserController extends Controller {
	
	//	定义事件名字
	const EVENT_USER_LOGIN = 'user_login';
	
	public function __construct(){
		//	绑定事件
		$this->on(self::EVENT_USER_LOGIN,['app\models\OLog','add']); 
		$this->on(self::EVENT_USER_LOGIN,['app\models\Admin','sendMail']); 
		$this->on(self::EVENT_USER_LOGIN,['app\models\User','notifyFirend']); 
	}
	
	public function actionIndex(){
		.....
		//	login				
	}
}
use app\events\UserLoginEvent;

class UserController extends Controller {
	
	.......
	.......
	
	public function actionIndex(){
		// 这里有一些代码.....
		Yii::$app->user->login($user);
		
		$event = new UserLoginEvent();
		$event->userId = $user->id;
		
		$this->trigger(self::EVENT_USER_LOGIN,$event); 						
	}
}

// event/UserLoginEvent.php
namespace app\events;

use yii\base\Event;

class UserLoginEvent extends Event {

    public $userId = 0;
}

app\controllers\UserController.php

use app\events\UserLoginEvent;

class UserController extends Controller {
	
	.......
	.......
	
	public function actionIndex(){
		// 这里有一些代码.....
		Yii::$app->user->login($user);
		
		$event = new UserLoginEvent();
		$event->userId = $user->id;
		
		$this->trigger(self::EVENT_USER_LOGIN,$event); 						
	}
}


// User app\models\User.php
class User {
	static public function notifyFirend($event){
		$userId = $event->userId;
		echo "告诉了朋友们我登陆了";
	}
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值