Laravel 5命令总线的最佳实践



我正在尝试重构控制器,并查看了Laravel的命令总线。

在阅读了一堆文章和观看了一些视频之后,我觉得这可能是重构我的控制器的好方法。

然而,似乎我也不应该从命令返回任何东西。

使用命令时您遵循命令-查询分离(CQS)原则:函数是查询(即它返回的东西)或命令(即它影响状态)。两者都是相互排斥的。所以命令不是应该返回任何东西,查询不应该修改任何东西。源

我创建了命令CreateCustomerCommand:
namespace AppCommands;
use QuickBooks_IPP_Service_Customer;
use AppCommandsCommand;
use IlluminateContractsBusSelfHandling;
class CreateCustomer extends Command implements SelfHandling
{
    private $qb;
    private $customer_service;
    private $customer;
    private $is_same_address;
    private $name;
    private $primary_phone;
    ...
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->qb = Quickbooks::Instance();
        $this->qb->ipp->version(QuickBooks_IPP_IDS::VERSION_3);
        $this->customer_service = new QuickBooks_IPP_Service_Customer();
        $this->is_same_address = $request->input('customer.isSameAddress');
        $this->name = ucwords(strtolower($request->input('customer.name')));
        $this->primary_phone = $request->input('customer.primaryPhone');
    }
    ...
    /**
     * Execute the command.
     *
     * @return void
     */
    public function handle()
    {
        $this->customer->setDisplayName($this->name);
        ...
        $this->customer_service->add(...);

    }
}

关于最佳实践的三个问题:

  1. 呼叫$this->customer_service->add()后,返回客户id。我如何将这个id发送回控制器?

  2. 在哪里合并活动日志最好?

活动:

$activity = new Activity();
$activity->event = 'Created Customer: ' . $this->name;
$activity->user = Auth::user()->name;
$activity->save();

最好在CreateCustomerCommand的末尾包含这个吗?

  • 事件呢?
  • 事件:

    event(new CustomerWasCreatedOrUpdated);
    

    我是新的应用程序架构,我正在寻找一种方法来保持我的控制器简单和可维护。如果有人能给我指出正确的方向,我会很高兴的。

    首先,感谢您努力保持您的控制器"简单和可维护"。你可能并不总能实现这个目标,但朝着这个目标努力往往会有回报。

    如何将ID发送回控制器?

    命令是一般服务的特殊情况。您的命令可以自由地声明额外的公共方法来查询状态更改的结果。如果命令由CLI应用程序使用,则该应用程序可能执行类似echo $this->command->getAddedCustomerId()的操作。基于web的控制器也可以类似地使用它。

    然而,您引用的建议——要么更改状态而不输出,要么查询有输出——是明智的。如果您正在更改状态,您需要知道更改该状态的结果,那么您可能正在滥用命令。

    作为一个类比,考虑Linux命令"useradd",您可以像调用useradd -m 'Clara Barton' cbarton那样调用它。该命令运行后,只给出成功或失败的指示。但是请注意,给了它一个主键, "cbarton"。您可以独立地查询该键,如grep cbarton /etc/passwd,但重要的是useradd没有为您创建ID。

    总之,改变状态的命令最多只能告诉你成功或失败。如果您希望检查状态更改的结果,则应该为该命令提供定位状态更改所需的键。

    所以你可能想要的是一个通用服务。命令可能会使用该服务,控制器可能会使用该服务,模型可能会使用该服务。但服务只是一个执行一项任务的通用类,并为您提供必要的API。

    在哪里合并活动日志?

    假设您没有使用PHP-AOP,应该预先建立一个仔细而严格的活动日志记录实践,并在整个开发生命周期中遵循。

    在很大程度上,活动日志的位置取决于系统的主要体系结构模型。如果您非常依赖事件,那么Event facade的扩展或日志事件可能是一个好地方。如果你广泛地依赖于DI,那么你可以在你认为需要日志记录的代码中传递Logger。

    在命令的特定情况下,您可以选择任何一种方式,这同样取决于您的主要体系结构模型。如果您避免使用事件,那么您将通过Laravel的普通类型提示DI注入记录器。如果您利用事件,那么您可能会做Event::fire('log', new LogState('Blah Blah', compact ($foo, $bar)));

    也就是说,最重要的是你依赖于一个可插拔和可配置的日志服务,一个你可以替换和调整测试、QA和生产需要的日志服务。

    事件呢?

    嗯,事件是伟大的。直到他们不是。根据我的经验,事件会变得非常复杂,因为在我看来,被滥用来传递数据和影响状态。

    事件就像传送器:你正沿着一条路径前进,然后事件触发,突然你被传送到整个代码库并弹出到一个完全不同的地方,然后你做一些事情并回到你原来的地方。当事件发生时,你必须以某种方式思考,并有效地遵循代码。

    如果Laravel事件是您对事件的第一次介绍,我不建议您过多地利用它们。相反,我建议您将它们限制在一个特定的包或应用程序的一部分中,直到您感受到它们提供的功能,以及它们所要求的架构和开发的严谨性。

    最新更新