geekcell / ddd-bundle
Symfony 中实用主义领域驱动设计的包。
Requires
- doctrine/orm: ^2.12
- geekcell/container-facade: ^1.0
- geekcell/ddd: ^1.1.0
- symfony/config: ^6.0 | ^7.0
- symfony/dependency-injection: ^6.0 | ^7.0
- symfony/event-dispatcher: ^6.0 | ^7.0
- symfony/http-kernel: ^6.0 | ^7.0
- symfony/messenger: ^6.0 | ^7.0
- symfony/string: ^6.0 | ^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.13
- mockery/mockery: ^1.5
- phpstan/phpstan: ^1.9
- phpstan/phpstan-beberlei-assert: ^1.1
- phpstan/phpstan-mockery: ^1.1
- phpunit/phpunit: ^9.5
- symfony/filesystem: ^6.0 | ^7.0
- symfony/framework-bundle: ^6.0
- symfony/maker-bundle: ^1.48
- symfony/yaml: ^6.0 | ^7.0
README
此 Symfony 包通过特定框架的实现增强 geekcell/php-ddd,以便在熟悉的环境中实现无缝的 领域驱动设计。
安装
要使用此包,请在 Composer 中要求它
composer require geekcell/ddd-bundle
生成命令
此包添加了几个 MakerBundle 命令,用于生成常用组件。
为了在您的 Symfony 项目中使用它们,您需要首先使用 composer 要求它
composer require symfony/maker-bundle
可用命令
make:ddd:command Creates a new command class and handler
make:ddd:controller Creates a new controller class
make:ddd:model Creates a new domain model class
make:ddd:query Creates a new query class and handler
make:ddd:resource Creates a new API Platform resource
构建块
模型 & 仓库
域模型是项目内部域概念和业务逻辑的表示。另一方面,仓库是一个抽象层,提供了一种访问和操作域对象的方法,而不暴露底层数据持久机制(如数据库或文件系统)的细节。
由于 Doctrine 是 Symfony 的实际持久层,因此此包还提供了一种基于 Doctrine 的仓库的(有偏见的)实现。
生成命令(s)
此命令可以用来生成
- 域模型类。
- 模型的仓库类。
- 模型的身份类作为值对象(可选)。
- Doctrine 数据库实体配置,可以是注解或单独的配置文件(可选)。
- 模型身份类的自定义 Doctrine 类型(可选)。
Description: Creates a new domain model class Usage: make:ddd:model [options] [--] [<name>] Arguments: name The name of the model class (e.g. Customer) Options: --aggregate-root Marks the model as aggregate root --entity=ENTITY Use this model as Doctrine entity --with-identity=WITH-IDENTITY Whether an identity value object should be created --with-suffix Adds the suffix "Model" to the model class name
聚合根 & 领域事件
可选地,通过继承自 AggregateRoot
,您可以将模型类制作为一个 聚合根,它用于封装一组相关对象,以及适用于它们的特性和规则。聚合根通常负责管理聚合内对象的生命周期,以及协调它们之间的任何交互。
AggregateRoot
基类附带了一些有用的功能,用于记录和分发 领域事件,这些事件代表软件系统领域中的重大事件或状态变化。
生成命令(s)
不适用
示例用法
// src/Domain/Event/OrderPlacedEvent.php use GeekCell\Ddd\Contracts\Domain\Event as DomainEvent; readonly class OrderPlacedEvent implements DomainEvent { public function __construct( public Order $order, ) { } } // src/Domain/Model/Order.php use GeekCell\DddBundle\Domain\AggregateRoot; class Order extends AggregateRoot { public function save(): void { $this->record(new OrderPlacedEvent($this)); } // ... } // Actual usage ... $order = new Order( /* ... */ ); $order->save(); $order->commit(); // All recorded events will be dispatched and released
提示:如果您想直接分发事件,请使用 AggregateRoot::dispatch()
而不是 AggregateRoot::record()
。
如果您不能(或不想)从 AggregateRoot
继承,您可以使用 DispatchableTrait
作为替代,为任何类添加分发功能。然而,前者是推荐的方式。
命令 & 查询
您可以使用 CommandBus
和 QueryBus
作为服务来实现 CQRS。内部,这两个总线都将使用 Symfony messenger 来分发命令和查询。
生成命令(s)
这些命令可以用来生成
- 命令和命令处理类。
- 查询和查询处理类。
生成的查询/命令只是一个空的类。处理器类被注册为配置的Symfony Messenger的消息处理器。
Description: Creates a new query|command class and handler Usage: make:ddd:query|command [<name>] Arguments: name The name of the query|command class (e.g. Customer)
示例用法
// src/Application/Query/TopRatedBookQuery.php use GeekCell\Ddd\Contracts\Application\Query; readonly class TopRatedBooksQuery implements Query { public function __construct( public string $category, public int $sinceDays, public int $limit = 10, ) { } // Getters etc. } // src/Application/Query/TopRatedBookQueryHandler.php use GeekCell\Ddd\Contracts\Application\QueryHandler; #[AsMessageHandler] class TopRatedBookQueryHandler implements QueryHandler { public function __construct( private readonly BookRepository $repository, ) { } public function __invoke(TopRatedBookQuery $query) { $books = $this->repository ->findTopRated($query->category, $query->sinceDays) ->paginate($query->limit); return $books; } } // src/Infrastructure/Http/Controller/BookController.php use GeekCell\Ddd\Contracts\Application\QueryBus; class BookController extends AbstractController { public function __construct( private readonly QueryBus $queryBus, ) { } #[Route('/books/top-rated')] public function getTopRated(Request $request) { $query = new TopRatedBooksQuery( /* extract from request */ ); $topRatedBooks = $this->queryBus->dispatch($query); // ... } }
控制器
一个标准的Symfony控制器,但增加了命令和查询总线。
生成器命令
此命令可用于生成控制器,可选地添加QueryBus
和CommandBus
依赖项。
Description: Creates a new controller class Usage: make:ddd:controller [options] [--] [<name>] Arguments: name The name of the model class (e.g. Customer) Options: --include-query-bus Add a query bus dependency --include-command-bus Add a command bus dependency
资源
一个API Platform资源,但与使用组合实体/资源方法的标准方法不同,更倾向于将模型(领域层)和API Platform特定资源(基础设施层)分开。
生成器命令
API Platform所需的最小版本是2.7,用于新元数据系统。
Description: Creates a new API Platform resource Usage: make:ddd:resource [options] [--] [<name>] Arguments: name The name of the model class to create the resource for (e.g. Customer). Model must exist already. Options: --config Config flavor to create (attribute|xml).