x2ts的事件总线

有的时候我们会需要在主线流程之外处理一些支线任务,比如用户注册的主线任务是检查和保存用户的各种资料,同时存在支线任务是给邀请此用户来注册的另一用户发送一条邀请成功通知。直观的写法是把发送通知的代码直接追加在注册程序的保存命令之后,这样的写法一个还不打紧,再多写几个就会破坏现有程序的可维护性,比如注册就赠送一个体验产品订单,还有注册成功要向统计系统发个消息通知……

基于事件模型来写这种支线程序可以让代码组织得更好。注册部分的代码只专注于注册该干的事情——检查数据、创建用户对象、设置用户资料、写入数据库,然后触发“用户注册”事件,后面的通知、馈赠、统计等支线行为,应该由监听用户注册事件的一众程序来处理,它们可以写在关联事件监听器的地方,也可以写在相应业务的模块里。

function notifyInvitor(event\user\Register $ev) {
    $user = $ev->user;
    if ($user->invitation) {
        //发送通知给邀请的用户
    }
}
X::bus()
    ->on('user.register', 'notifyInvitor')
    ->on('user.register', ['Product', 'presentTrial'])
    ->on('user.register', ['Statistic', 'userRegister'];

在用户注册的主业务代码中,只需要触发此事件即可:

//各种检查和赋值
$user->save();
X::bus()->dispatch(new event\user\Register([
    'dispatcher' => $this,
    'user'       => $user,
]));

x2ts框架的事件也已转向使用事件总线。所谓事件总线,意思是所有事件都在挂载在同一个对象上,并且所有事件都在同一个对象上触发,这样一来,开发事件处理函数的人无需了解事件触发的程序细节,只要根据文档选择适当的事件,即可开发回调函数,完成支线任务。所有的x2ts框架事件,都定义在x2ts开头的命名空间下;所有的应用层事件,都定义在event开头的命名空间下,代码保存在项目的protected/event目录中。

许多时候事件处理代码只是一些小函数,没有完整的class或者模块承载,为了更好的管理这些函数,项目加入了一个event\Setup类,位于protected/event/Setup.php里,在这个类里可以写静态方法作为事件监听器函数。还有一个静态方法setup()负责注册这些事件监听器。事件监听写的书写原则是为每一个任务编写一个静态方法,名称和要做的事情相符,比如notifyInvitor表示此方法会发送通知给邀请人,sendAskAnsweredNotify表示发送答疑回复通知等等。

标签: x2ts, event

已有 2 条评论

  1. dearmrli dearmrli

    x2ts\event\Event 中的成员变量$state 是要用来做什么的,目前没看到有使用的地方

    1. xts xts

      在用X::bus()->on(...)挂载事件时,可以将依赖的上下文数据以$state传入,在事件触发时,$state将以事件对象的一个属性传回。

添加新评论