在这篇文章中,我们将学习什么是“事件驱动编程”,以及如何在Laravel中开始构建一个事件驱动的应用程序。同时,我们也会看到如何通过事件驱动编程来解耦应用程序的逻辑。开始之前先说明一下,本文主要讲解事件驱动的编程思想和概念,不会涉及到LaravelEvents的方方面面。如果您需要更全面地了解Laravel事件及其各种用途,请访问Laravel事件文档以获取详细信息。什么是事件驱动编程在我们深入研究事件驱动应用程序之前,让我们先看一下维基百科中事件驱动编程的定义:事件驱动编程是一种编程模型,其中程序流程由用户操作决定,例如)、传感器输出或来自其他程序/线程的消息来确定确定。事件驱动编程是图形用户界面和其他应用程序(例如JavaScriptWeb应用程序)中使用的主要范例,用于执行特定操作以响应用户输入。事件驱动的应用程序响应用户的操作,然后执行相应的代码以响应用户的操作。Laravel事件根据上面的定义,事件是在应用程序中发生的动作。Javascript事件是用户操作,例如鼠标单击、鼠标悬停和键盘按下。Laravel中的事件是应用程序中发生的动作,例如邮件通知、日志记录、用户注册、CRUD操作等。LaravelEvents系统提供了观察者模式的简单实现,允许开发者订阅和监听发生在应用程序中的动作应用程序。应用程序中的一些事件是由Laravel框架自动发起的。例如,当使用Eloquent模型执行创建、保存、更新或删除操作时,Laravel将分别发起创建、保存、更新和删除事件。如果有必要,我们可以监听这些事件来执行相应的代码来完成我们自己的需求。除了Laravel框架自动发起的事件,我们还可以让Laravel根据自己应用的需要来发起自己定义的事件。例如,您可以发起一个userRegistered事件,并在事件处理程序中发送一封用户验证邮件,以便新注册的用户可以验证他们的邮箱。引发事件不会使应用程序执行任何相应的操作,我们必须在事件处理程序中相应地响应引发的事件。Laravel事件由事件处理器和事件监听器两部分组成。事件处理程序包含与启动事件相关的信息。EventListener监听事件对象并对事件做出响应。事件监听器是我们实现事件逻辑的地方。在Laravel中,Event类文件存放在app/Events目录下,Listener类文件存放在app/Listeners目录下。为什么使用事件驱动编程既然我们了解了事件驱动应用程序和LaravelEvents的概念,您可能想知道为什么要采用事件驱动的方法来构建您的应用程序。让我们来看看事件驱动编程的好处。首先,事件是分离应用程序各个方面的好方法,因为单个事件可以有多个互不依赖的侦听器。通过解耦,您不会用不适合您的域逻辑的代码污染您的代码库。其次,由于应用程序是松散耦合的,您可以轻松地扩展应用程序的功能,而不必中断/重写应用程序或应用程序的某些其他功能。应用程序示例现在假设在新用户注册我们的应用程序后,应用程序将向用户发送一封欢迎电子邮件,并自动为用户订阅应用程序上的每周时事通讯。当不应用事件驱动方法时,代码通常如下://不使用事件驱动方法publicfunctionregister(Request$request){//validateinput$this->validate($request->all(),['name'=>'required','email'=>'required|unique:users','password'=>'required|min:6|confirmed',]);//创建用户并保存在数据库中$user=$this->create($request->all());//发送欢迎邮件Mail::to($user)->send(newWelcomeToSiteName($user));//为用户注册每周时事通讯Newsletter::subscribe($user->email,['FNAME':$user->fname,'LNAME':$user->lname],'SiteNameWeekly');//登录新注册的用户$this->guard()->login($user);returnredirect('/home');}您可以看到发送欢迎电子邮件和订阅时事通讯的逻辑与register方法紧密耦合。根据关注点分离原则,注册方法不应该关心发送欢迎邮件和新闻订阅的具体实现。你可能认为在register方法中发送欢迎邮件和订阅新闻不算什么,但是如果你在注册时除了发送邮件之外还给用户发送短信怎么办?继续在注册方法中写入:publicfunctionregister(Request$request){//验证输入//创建用户并保存在数据库中//发送欢迎邮件Mail::to($user)->send(newWelcomeToSiteName($user));//发送短信Nexmo::message()->send(['to'=>$user->phone_number,'from'=>'SiteName','text'=>'欢迎并感谢您在SiteName上注册。]);//为用户注册每周时事通讯Newsletter::subscribe($user->email,['FNAME':$user->fname,'LNAME':$user->lname],'SiteNameWeekly');//loginnewregistereduserreturnredirect('/home');}可以看到代码库已经变得臃肿了。现在让我们看看如何使用事件驱动的编程方法实现上述相同的功能。//使用事件驱动方法publicfunctionregister(Request$request){//验证输入$this->validate($request->all(),['name'=>'required','email'=>'必需|unique:users','password'=>'required|min:6|confirmed',]);//创建用户并保存在数据库中$user=$this->create($request->all());//创建用户后触发事件event(newUserRegistered($user));//登录新注册的用户$this->guard()->login($user);returnredirect('/home');}创建用户后,将触发UserRegistered事件。回想一下我们之前提到的应用程序在触发事件后不会自行执行任何操作,我们需要侦听UserRegistered事件并执行必要的操作。让我们创建UserRegistered事件类以及SendWelcomeMail和SignupForWeeklyNewsletter监听器类:>[SendWelcomeMail::class,SignupForWeeklyNewsletter::class,],];打开app/Events/UserRegistered.php文件,更新其构造方法:public$user;publicfunction__construct(User$user){$this->user=$user;}将$user声明为public,它将传递给监听器,监听器可以使用它来执行必要的逻辑。接下来,事件侦听器将在其处理方法中接收事件实例。在handle方法中,我们可以执行响应事件的操作。//app/Listeners/SendWelcomeMail.phppublicfunctionhandle(UserRegistered$event){//发送欢迎邮件Mail::to($event->user)->send(newWelcomeToSiteName($event->user));}//app/Listeners/SignupForWeeklyNewsletter.phppublicfunctionhandle(UserRegistered$event){//为用户注册每周时事通讯Newsletter::subscribe($event->user->email,['FNAME':$event->user->fname,'LNAME':$event->user->lname],'SiteNameWeekly');}可以看出,在事件驱动的方式下,我们把register方法的代码尽可能的小,关注用户注册,其他逻辑由UserRegistered事件的监听器处理,现在如果我们想在用户注册后给新注册的用户发送一条短信,我们只需要创建一个新的事件监听器来监听当触发UserRegistered事件时phpartisanmake:listenerSendWelcomeSMS--event=UserRegistered//app/Listeners/SendWelcomeSMS.phppublicfunctionhandle(UserRegistered$event){//发送短信Nexmo::message()->send(['to'=>$event->user->phone_number,'from'=>'SiteName','text'=>'欢迎并感谢您在SiteName上注册。']);注意:记得更新EventServiceProvider中的$listen属性结论在本文中,我们已经能够理解什么是事件驱动编程,什么是事件驱动应用程序以及什么是Laravel事件我们还了解了事件驱动应用程序的优势。然而,就像所有具有积极意义的编程概念一样,它也有缺点。事件驱动应用程序的主要缺点是它使程序流程复杂化,特别是对于刚接触开发的人来说,可能很难真正理解应用程序的流程。以上面的实现为例,通过register方法,我们不能直观的看出程序在创建用户后会向新用户发送欢迎邮件,并在时事通讯中进行注册。所以在开发中,你应该根据场景创造性地使用它,利用它的优点来解耦你的应用程序,不要过度使用它。
