
本文的翻译是为专业课程“ Framework Laravel”的学生准备的
Frek Van der Herten和Spatie团队在Laravel Event Projector上进行了很长时间的工作,该软件包使您可以将Event Sourcing概念应用于Laravel框架。 最后,第一个稳定版本(v1.0.0)可用!
您可以使用composer将Event Projector安装到项目中,并且由于Laravel中的自动数据包检测功能,因此在发布软件包迁移和配置后即可立即开始工作!
composer require spatie/laravel-event-projector:^1.0.0
Event Projector需要PHP 7.2,因此您的应用程序必须支持最新版本的PHP,尽管Laravel框架本身需要的PHP版本至少为7.1.3。
什么是“事件生成”
在生成事件一文中,此概念描述如下:
而不是将数据的当前状态存储在域中,而是用于记录对此数据执行的整个操作序列,而是在仅附加模式下操作的存储仅添加数据。 该存储充当记录系统,可用于实现域对象。 这使我们可以简化复杂主题领域中的任务,因为不需要同步数据模型和主题领域,从而提高了可伸缩性,提高了生产率和运营效率。 这种方法可以确保事务数据的一致性,还可以使您保留完整的更改日志和历史记录,从而可以执行补偿性操作。
我建议您阅读全文。 它提供了对该模板的出色描述,表达了正确使用的注意事项,并描述了可能有用的情况。
我还喜欢对事件生成的概念的解释,该解释在 Event Projector文档的简介中给出:
关于数据的事件生成与关于代码的Git相同。 大多数应用程序仅将其当前状态存储在数据库中。 大量有用的信息丢失了-您不知道应用程序如何达到此状态。
事件生成的概念是通过保存应用程序中发生的所有事件来解决此问题的尝试。 应用程序的状态是通过侦听这些事件而形成的。
为了便于理解,请考虑生活中的一个小例子。 假设您是一家银行。 您的客户有帐户。 仅保留有关帐户余额的信息是不够的。 您还必须记住所有交易。 使用事件生成模板时,帐户余额将不仅是数据库中的单独字段,而是根据存储的交易信息计算出的值。 这只是事件生成概念提供的众多好处之一。
该软件包旨在使Laravel框架的用户熟悉事件生成的概念,并促进其在实践中的使用。
似乎Event Projector有助于简化事件生成模式的工作。 该文档还帮助我弄清楚了如何将这种方法用作我已经知道的Laravel框架概念的一部分。
Laravel Eventing基础
要了解Event Projector程序包中事件生成的工作方式以及此过程涉及哪些组件,您应该阅读“ 创建第一个投影仪”部分。
在较高的层次上(请原谅,如果我的评估不完全正确,因为事件的生成对我来说是一个新概念),使用事件投影仪进行的事件生成包括:
- 雄辩的模型
- 实现ShouldBeStored接口的事件
- 投影机类
文档中提供的带有createWithAttributes
静态方法的模型类示例:
namespace App; use App\Events\AccountCreated; use App\Events\AccountDeleted; use App\Events\MoneyAdded; use App\Events\MoneySubtracted; use Illuminate\Database\Eloquent\Model; use Ramsey\Uuid\Uuid; class Account extends Model { protected $guarded = []; protected $casts = [ 'broke_mail_send' => 'bool', ]; public static function createWithAttributes(array $attributes): Account { $attributes['uuid'] = (string) Uuid::uuid4(); event(new AccountCreated($attributes)); return static::uuid($attributes['uuid']); } public function addMoney(int $amount) { event(new MoneyAdded($this->uuid, $amount)); } public function subtractMoney(int $amount) { event(new MoneySubtracted($this->uuid, $amount)); } public function delete() { event(new AccountDeleted($this->uuid)); } public static function uuid(string $uuid): ?Account { return static::where('uuid', $uuid)->first(); } }
在这里,您需要注意分别触发的事件AccountCreated
, MoneyAdded
, MoneySubtracted
和AccountDeleted
,以打开一个帐户,向该帐户添加资金,从该帐户提取资金并删除该帐户。
下面是MoneyAdded
事件的示例(向帐户添加资金)。 ShouldBeStored接口告知Event Projector程序包应保存此事件:
namespace App\Events; use Spatie\EventProjector\ShouldBeStored; class MoneyAdded implements ShouldBeStored { public $accountUuid; public $amount; public function __construct(string $accountUuid, int $amount) { $this->accountUuid = $accountUuid; $this->amount = $amount; } }
最后,投影仪类中的事件处理程序的一个局部示例,用于补充帐户中的资金(我最喜欢的银行事件类型):
public function onMoneyAdded(MoneyAdded $event) { $account = Account::uuid($event->accountUuid); $account->balance += $event->amount; $account->save(); }
要将所有这些链接在一起,请考虑文档中的有关创建新帐户和添加资金的示例:
Account::createWithAttributes(['name' => 'Luke']); Account::createWithAttributes(['name' => 'Leia']); $account = Account::where(['name' => 'Luke'])->first(); $anotherAccount = Account::where(['name' => 'Leia'])->first(); $account->addMoney(1000); $anotherAccount->addMoney(500); $account->subtractMoney(50);
我怀疑卢克和莱亚帐户中的余额是以银河标准贷款表示的,尽管总的来说,我怀疑它们会公开进行此类操作。
使用此程序包生成事件的以下优点也吸引了我的注意力,这在文档中有所说明:
使用投影机时有趣的一点-它们可以在事件发生后创建。 想象一下,银行希望收到每个帐户的平均余额报告。 在这种情况下,创建新的投影仪,播放所有事件并最终获取此数据就足够了。
在活动结束时创建新投影仪的想法似乎很有希望。 事实证明,您不必事先获取所有“正确的”数据,但是您可以迭代得出结果。
关于性能,根据文档,对投影仪的访问“非常快”。
想了解更多?
首先,建议您阅读Event Projector文档 ,并确保已安装最新版本的PHP 7.2。 Spatie团队还在Laravel上上传了一个示例应用程序 ,展示了Event Projector软件包的功能。
您可以下载代码,用星号标记存储库,还可以为GitHub上的Event Projector项目的开发做出贡献。 在撰写本文时,项目Event Projector已经有15位参与者,他们的努力使1.0的稳定版本成为可能。 干得好,Spatie! 我相信Event Projector将是Laravel社区会赞赏的另一个很棒的软件包。