写点什么

Laravel 来信|Event

用户头像
LeastCoding
关注
发布于: 2021 年 02 月 22 日
Laravel来信|Event

max,你好


我是 Event,一个简单的观察者模式实现。我可以帮助你解藕业务代码,让你的系统更加健壮、更易维护。


也许,你会认为我在说大话。


那么,让我们一起用实际行动来证明我所言非虚吧。


首先,你认真考虑一下这样的业务场景,订单支付。当用户支付完完成后,要给用户发送一个微信消息,过了一段时间后又想在支付成功后给用户增加几个积分,如此等等。


对于这类业务变更,你是怎么做的呢?


我想大概会是这样的吧,在原有的业务逻辑处增加一个代码段,调用微信消息模块,之后再增加一个代码段,调用增加积分模块,就像下面这张图一样,一直往下堆叠,代码越来越多。。。



你同意我的观点吗,这样做不够好。


那接下来,看看我是怎么做的,看完后你自行对比下,是否比之前的更好。


我是这样做的,我把支付成功视为一个事件,当这个事件被触发后我就发送一个消息,然后消息监听者监听到这个消息后,各自执行自己应该做的事。就好比原来是一个人干多件事,现在是多个人,每个人只干一件事。


image.png


发现这样做的优点了吗?


当后面再有别的什么事要做的时候,我就只要增加相应的事件监听就好了,原有的业务逻辑也不存在改动。


这也是我们在开发中应该尽量避免的一件事,修改既有代码。


现在,我们再结合起来看看,这两种实现思路的不同之处。


image.png


好了,希望你能 get 到我的优点以及缺点。


如果你觉得我说的对,那就继续吧,看看我是如何一步步做到这点的。


第一次,过程稍微多了一点,需要四步。


  • 在 APP\Events\下新建一个事件类

  • 在 APP\Listeners\下新建一个监听类  

  • 在 APP\Providers\EventServiceProvider.php 文件中注册事件-监听关系

  • 在业务逻辑类中发送事件


第二次及以后,需要两步


  • 在 APP\Listeners\下新建一个监听类  

  • 在 APP\Providers\EventServiceProvider.php 文件中注册事件-监听关系


你对这个实现过程了解了吗?看看每个过程的具体实现吧。


  • 新建一个事件类 EventA


需要注意的地方有两个,一个是必须引入 Dispatchable,因为业务类会依赖其提供的 dispatch 方法,另一个是构造函数参数,因为不能确定后续的业务子流程需要哪些参数,最好是通过数组的形式将参数打包传进来,这样可以避免因为参数不足而引起的修改。


<?phpnamespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
class EventA{ use Dispatchable; private $data;
/** * Create a new event instance. * * @param \App\Models\Order $order * @return void */ public function __construct($data) { $this->data = $data; } public function getData(){ return $this->data; }}
复制代码


  • 新建一个监听类 ListenerEventA


监听类必须实现一个 handle 方法,其参数为要监听的事件类实例,然后可以通过 $event 实例的 getData()方法获取业务类传递过来的变量,来实现自己的具体操作。


<?phpnamespace App\Listeners;
use App\Events\EventA as Event;
class ListenerEventA{ /** * Handle the event. * * @param \App\Events\EventA $event * @return void */ public function handle(Event $event) { // $event->getData() 访问事件类data属性 //执行具体的业务逻辑 }}
复制代码


  • 在 APP\Providers\EventServiceProvider.php 文件中注册事件-监听关系


监听关系是一对多的关系,即一个事件类可以被多个监听类监听,这里体现为一个关联数组。


<?phpnamespace App\Providers;
use Illuminate\Auth\Events\Registered;use Illuminate\Auth\Listeners\SendEmailVerificationNotification;use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;use Illuminate\Support\Facades\Event;
//引入要注册的事件与监听类use App\Events\EventA;use App\Listeners\ListenerEventA;use App\Listeners\ListenerEventB;
class EventServiceProvider extends ServiceProvider{ protected $listen = [ EventA::class => [//一对多 ListenerEventA::class, ListenerEventB::class, ], ]; //..... 其他代码}
复制代码


  • 在业务逻辑类中发送事件


首先要引入事件类,然后在业务逻辑中调用事件类的 dispatch 方法来发送一个事件,这样就会触发一个事件,而监听了此事件的监听类就会执行。

<?phpuse APP\Events\EventA;//引入事件类
//.....其他代码
//事件发送代码段$data = array( 'key1'=>'value1', 'key2'=>'value2');
EventA::dispatch('自定义一个事件名',$data); //发送事件
复制代码


自己去动手尝试一下吧。


用户头像

LeastCoding

关注

I Know Nothing! 2021.01.01 加入

班门弄斧,分享一点自己的经验与思想!

评论

发布
暂无评论
Laravel来信|Event