【问题标题】:What's the difference between Commands and Events in the context of Laravel 5?Laravel 5 上下文中的命令和事件有什么区别?
【发布时间】:2015-02-05 12:29:12
【问题描述】:

所以 Laravel 5 终于在昨天发布了命令总线的最终实现,但我在徘徊,使用命令总线与我们在之前版本中的事件机制有什么真正的区别?

好的,我明白了它可用于从 Request 对象创建命令的原因,这非常有用,但除此之外,它的行为方式似乎与现在的事件的整个排队功能相似?

您能否提供用例示例以及两者的优缺点?

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:
    • 命令是即将发生的事情。即“创建用户”
    • 事件是现在刚刚发生的事情 - 即“UserSuccessfullyCreated”

    差异似乎很小 - 但有一些关键差异。

    • 必须专门调用/调度命令。 IE。如果你想 执行 CommandX - 您必须在某处调用 CommandX。
    • 事件响应在您的应用程序中触发任何地方的事件。 最棒的是多个事件处理类可以响应 相同的事件

    让我们举一个例子来最好地说明它。假设我们创建了一个用户,我们想向他们发送一封欢迎电子邮件并更新我们的时事通讯列表。

    在命令场景中会这样做

    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));
        }
    

    然后我们可以创建尽可能多的事件来监听该事件并做一些事情:

    事件类A

    Event::listen('UserWasCreated', function($event)
    {
        // 2. Send welcome email
    });
    

    事件类B

    Event::listen('UserWasCreated', function($event)
    {
        // 3. Update our newsletter
    });
    

    最重要的是关注点分离。命令“createuser”现在不需要担心用户创建之后会发生什么。它只需要CreateUser

    另外 - 如果我们想在用户注册后添加另一个功能 - 比如说在乐透抽奖中输入它们 - 你可以添加另一个事件类并添加一个新的事件监听器。

    事件类C

    Event::listen('UserWasCreated', function($event)
    {
        // 4. Register them in lotto
    });
    

    注意我们如何不需要触摸命令 CreateUser 类代码?这在 OOP 风格的方法中提供了真正的类分离关注点。

    【讨论】:

    • 很容易理解:)
    • 谢谢。完美的解释。
    【解决方案2】:

    我只想在正确答案的基础上分享我对这个概念的理解:

    主要区别在于命令可以更改模型状态,而事件只是对状态更改做出反应。

    命令:

    Laravel 中的命令代表Command 设计模式的实现。

    命令的主要出现:

    • 可以从任何地方访问
    • 任何其他开发人员都很容易阅读它们

    在 Laravel 5 中创建命令:

    你需要生成一个命令DTO(可以实现SelfHandling接口)。使用php artisan make:command {command-name}

    示例:php artisan make:command Course/PostCourseCommand

    命令的命名约定:说商业语言并在其中添加后缀命令

    要从您的控制器调用(调度)命令,您可以使用:

    $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 目录,这样做:

    1. 通过 artisan 生成命令处理程序

    art handler:command --command="Course/PoatCourseCommand"

    1. 从 Command 类中移除 SelfHandling 接口,以便它会搜索处理程序来处理它。

    活动:

    Laravel 中的事件代表Observer 设计模式的实现。

    在 Laravel 5 中创建事件:

    1. 使用工匠:art make:event {event-name}

    示例:art make:event LogSomething

    1. 为该事件生成事件处理程序

    art handler:event LogSomething --event="LogSomething"

    1. 在事件服务提供者(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

    您还可以在不创建事件处理程序或在侦听器数组中注册列表器的情况下侦听事件,只需转到事件服务证明程序并在引导函数中编写您的事件及其操作(不推荐)。示例:

    Event::listen('XXX\Events\DoSomethingElse', function($event)
    {
        dd('handle me :)');
    });
    

    最后:您可以对事件进行排队,甚至可以从类本身中订阅多个事件..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-20
      • 1970-01-01
      • 2012-01-01
      • 2021-05-27
      • 2023-01-26
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多