所以Laravel 5最终在昨天终于发布了命令总线的最终实现,但是我在徘徊,在先前版本中使用命令总线而不是事件机制的真正区别是什么?
好的,我看到它可以用来从Request对象创建命令的原因,这是非常有用的,但除此之外,它似乎以类似的方式表现甚至现在的事件的整个排队功能?
您能否提供一些用例示例以及两者的优缺点?
答案 0 :(得分:63)
差异似乎很小 - 但存在一些关键差异。
让我们举一个例子来说明它。假设我们创建了一个用户,我们希望向他们发送欢迎电子邮件,并更新我们的新闻通讯列表。
在命令场景中会做
AdminController {
function create() {
Bus::dispatch(new CreateUser(Auth::user());
}
}
然后在我们的CommandClass中 - 我们会做
public function handle(CreateUser $auth)
{
// 1. Create the user here
// 2. Send welcome email
// 3. Update our newsletter
}
但是如果我们使用事件 - 我们会在CommandClass中执行类似的操作
public function handle(CreateUser $auth)
{
// 1. Create the user here
Event::fire(new UserWasCreated($user));
}
然后我们可以创建尽可能多的事件来听取该事件并执行某些操作:
EventClassA
Event::listen('UserWasCreated', function($event)
{
// 2. Send welcome email
});
EventClassB
Event::listen('UserWasCreated', function($event)
{
// 3. Update our newsletter
});
最重要的是分离关注点。命令" createuser"现在不需要担心在创建用户之后会发生什么。它只需要 CreateUser 。
另外 - 如果我们想在用户注册后添加另一个功能 - 比如在乐透画中输入它们 - 你可以添加另一个事件类并添加一个新的事件监听器。
EventClassC
Event::listen('UserWasCreated', function($event)
{
// 4. Register them in lotto
});
请注意我们如何不需要触摸命令CreateUser类代码?这提供了OOP风格方法中类的真正分离问题。
答案 1 :(得分:5)
我只想在正确的答案之上分享我对这个概念的理解:
主要区别在于命令可以更改模型状态,而事件只会对状态更改做出反应。
<强>命令:强>
Laravel中的命令代表Command设计模式的实现。
命令的主要冒险:
在Laravel 5中创建一个命令:
您需要生成命令DTO(可以实现SelfHandling接口)。使用php artisan make:command {command-name}
示例:php artisan make:command Course/PostCourseCommand
命令的命名约定:说出业务语言并向其添加postfix命令
要从您的控制器调用(调度)命令,您可以使用:
$this->dispatch(new PostCourseCommand())
或
Bus::dispatch(new PostCourseCommand());
旁注: “从请求调度”功能是一种很好的方法,可以逐个跳过将变量传递给命令构造函数,而不是为您解决这个问题:
示例:
$test_request = Request::create('/test', 'GET', [
'name' => 'Mahmoud',
'nickname' => 'Mega'
]);
$result = Bus::dispatchFrom(
CreateCourse::class, $test_request
);
最后:
您可以将处理程序函数及其逻辑从命令DTO分离到Handlers目录,以执行此操作:
art handler:command --command="Course/PoatCourseCommand"
<强>事件:强>
Laravel中的事件代表Observer设计模式的实现。
在Laravel 5中创建一个事件:
art make:event {event-name}
示例:art make:event LogSomething
art handler:event LogSomething --event="LogSomething"
(app/Providers/EventServiceProvider.php)
示例:
protected $listen = [
\Zzz\Events\LogSomething::class => [ // event.name
\Zzz\Handlers\Events\LogSomething::class, //EventListener
],
],
致电(开火)一个事件:
使用:
Event::fire(New LogSomething());
或者您可以使用事件助手
event(New LogSomething());
旁注: 或者,您只需在服务提供程序中注册事件然后运行此命令即可生成事件。
php artisan event:generate
&lt;&lt;这将自动为您添加两个类
此外,您可以在不创建事件处理程序或在侦听器数组中注册列表器的情况下监听事件,只需转到事件服务证明器并在引导函数内部编写事件及其操作(不推荐)。例如:
Event::listen('XXX\Events\DoSomethingElse', function($event)
{
dd('handle me :)');
});
最后:您可以对一个事件进行排队,甚至可以从类本身内订阅多个事件。