当我的一个模型被保存(创建/更新)或删除时,我需要运行一些代码。最好的方法是什么?
我知道有三种不同的方式:
我没有看到这些比较和对比,所以我不知道有什么区别。我担心在某些情况下事件不会发生。
例如,在Django中,只有在逐个删除模型时才删除火,而不是在批量删除中删除。
为了明确起见,我正在寻找比较和对比这些(或其他)方法的答案--而不是简单地提出更多的方法来做同样的事情。
发布于 2016-10-19 12:55:29
这三种方法和第四种方法由@joko推荐。可能还有更多,但让我们关注这4种方法。
让我逐一描述一下:
1)覆盖模型上的保存和删除方法
在此方法中,您将使用OOPD方法重写。您正在重写Laravel的interal save方法,并通过在其之上定义您自己的save方法来添加您的附加代码。在Laravel不断发展的过程中,应该避免这种情况,如果进行了重大更改,就可能会发生这种情况,比如在将来用任何其他保存记录的方法替换save方法。再一次,您必须创建另一个方法来覆盖该新方法。此外,在这里编写代码可能会增加您的模型类文件。你的模型可能会继续处理他不该处理的事情(例如:发送电子邮件)。这种方法应该避免。。
2)在引导方法中添加创建/更新/删除回调
这里您正在定义模型的Boot方法上的代码。只有在事件中需要处理的代码/事情很少时,才应该使用此方法。这种方法的缺点是,它使代码变得更加复杂和混乱,因为您可以像函数式编程一样将所有逻辑写在一起。假设您必须在创建之前和创建之后做一些事情。你的boot方法将会增长。
3)在引导方法中绑定一个观察者
这个方法很好。您创建了一个观察者类,它处理类似于Laravel事件应该发生的事情。它使代码更加简洁,易于维护。
示例:假设您必须在这些方法中用creating、saving、saved、deleting编写代码。在这种情况下,方法1)和方法2)将不是很好的实践,因为在
方法1:我们必须创建这4个方法并覆盖它们,并在将来的Laravel版本中支持它们。在这种情况下,您的模型中的代码也会增长,因为重写了这些方法
方法2: --在本例中--您的boot方法也会增长,因此您的模型文件将成为一堆垃圾代码。
在方法1和方法2中,请记住,您的模型没有责任完成您将要编写的许多内容。就像创建用户时发送电子邮件一样。这些代码最终可能会用created方法编写。
假设您现在有一个场景,您需要在created事件上向用户发送电子邮件,还需要在customer中使用户的输入日志用户。然后,您必须用相同的方法为这两种方法编写代码。也许,你不可能遵循单一的责任原则。在这种情况下我们该怎么办?见方法4。
4) @joko建议的其他方法
我在方法4的结尾中建议的场景。您可以发送电子邮件给用户,并登录客户关系管理,无论何时创建。然后,您的方法将做两件事(发送电子邮件和登录CRM)。不得遵循单一责任原则。如果我们能把它们都解耦呢。然后是这个方法。
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'eloquent.saved: App\User' => 'App\Listeners\SendWelcomeEmailToUser'
'eloquent.saved: App\User' => 'App\Listeners\LogUserInCRM'
];
}创建两个侦听器类
class SendWelcomeEmailToUser
{
public function handle(User $user){
// Write code to send email
}
}
class LogUserInCRM
{
public function handle(User $user){
// Write code to log
}
}通过这个,你可以分离出代码,并使它们更加干净。
我一般更喜欢这种方法,它的模式干净。它还让您更好地了解事件发生时实际发生的情况。它成为事件到侦听器映射的一个单一点。
发布于 2016-10-17 06:24:40
您可以为模型的每一个创建/更新创建事件处理程序,例如为缓存刚刚保存到数据库或要保存到数据库的模型数据,无需选择查询调用即可更容易地检索,而删除调用则用于缓存处理程序事件上的给定键删除缓存以及从数据库中删除。
发布于 2016-10-18 00:29:10
当你需要确切地知道事情是如何做的时,我倾向于手工处理。最近,我使用这个Laravel样板启动了一个项目,我喜欢它们在更新模型时在存储库中手动触发事件的方式:
由于模型应该始终通过存储库进行更新,所以您总是需要手动决定如何处理事件。当多个模型被删除时,您可以触发您自己的事件,并采取相应的行动。不过,你所有的选择都会奏效,你只需要找到最适合你需求的选项。
https://stackoverflow.com/questions/31375165
复制相似问题