梦游者/聚合根

此包已弃用且不再维护。作者建议使用梦游者/domain包。

实现触发领域事件的聚合根

1.0.0 2018-06-06 20:02 UTC

This package is auto-updated.

Last update: 2020-02-03 17:23:34 UTC


README

此存储库已归档。请更新到合并的包。

聚合根

实现了一个通用的聚合根,用于在实体中触发领域事件。

要求

  • PHP 7+

安装

使用composer安装,或从github.com/checkout / pull文件。

  • composer install somnambulist/aggregate-root

使用

聚合是领域驱动设计的一个概念,封装了一组相关的领域概念,应该一起管理。请参阅Fowler: 聚合根示例包括:订单、用户、客户。在您的领域代码中,只应加载聚合。

首先确定您的领域对象中哪些是聚合根。然后扩展抽象聚合根到您的根实体。这是更改该对象树的入口点。

接下来:实现您的领域逻辑,并为聚合应允许/管理的每个更改触发适当的事件。

触发事件

要触发一个事件,确定哪些操作应导致领域事件。这些应该与领域对象的状态变化一致,事件应来自您的主要实体(聚合根)。

例如:您可能希望在创建新的用户实体或添加角色到用户时触发事件。

这确实需要更改您通常与实体和Doctrine一起工作的方式,您应删除设置器和可空的构造函数参数。相反,您将通过特定方法管理实体更改,例如

  • completeOrder()
  • updatePermissions()
  • revokePermissions()
  • publishStory()

在内部,在更新实体状态后,调用:$this->raise(new NameOfEvent([]))并将任何特定参数传递到您希望可供监听器使用的的事件中。这可能包括旧值与新值或整个实体引用,完全取决于您。

public function __construct($id, $name, $another)
{
    $this->id        = $id;
    $this->name      = $name;
    $this->another   = $another;
    
    $this->>initializeTimestamps();
    
    $this->raise(new MyEntityCreatedEvent(['id' => $id, 'name' => $name, 'another' => $another]));
}

通常,最好不要在构造函数中触发事件,而应使用命名构造函数进行主要对象创建

private function __construct($id, $name, $another)
{
    $this->id        = $id;
    $this->name      = $name;
    $this->another   = $another;
    
    $this->>initializeTimestamps();
}

public static function create($id, $name, $another)
{
    $entity = new static($id, $name, $another, new DateTime());
    $entity->raise(new MyEntityCreatedEvent(['id' => $id, 'name' => $name, 'another' => $another]));
    
    return $entity;
}

处理时间戳

处理聚合时,聚合应保持其状态;这包括任何时间戳。如果这些被延迟到数据库或ORM层,那么您的聚合正在单独于状态更改之外进行更改。

不要依赖于ORM或数据库,您应该使用Timestampable特质中的initializeTimestamps()updateTimestamps()方法,或者自行实现类似逻辑。然后在您的聚合(和其他实体)中,每次发生变化时,务必调用updatedTimestamps()

触发领域事件

有关从聚合根触发领域事件的策略,请参阅领域事件

请务必阅读之前提到的Benjamin Eberlei的文章,并查看他的断言库,用于低依赖性实体验证。