定制 geekcell/ddd-bundle 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

geekcell/ddd-bundle

最新稳定版本:1.4.3

Composer 安装命令:

composer require geekcell/ddd-bundle

包简介

A bundle for pragmatic domain driven design in Symfony.

README 文档

README

This Symfony bundle augments geekcell/php-ddd with framework-specific implementations to enable seamless domain driven design in a familiar environment.

Installation

To use this bundle, require it in Composer

composer require geekcell/ddd-bundle

Generator Commands

This bundle adds several MakerBundle commands to generate commonly used components.

In order to use them in your Symfony project, you need to require it with composer first

composer require symfony/maker-bundle

Available Commands

  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

Building Blocks

Model & Repository

The domain model is a representation of the domain concepts and business logic within your project. The repository on the other hand is an abstraction layer that provides a way to access and manipulate domain objects without exposing the details of the underlying data persistence mechanism (such as a database or file system).

Since Doctrine is the de-facto persistence layer for Symfony, this bundle also provides an (opinionated) implementation for a Doctrine-based repository.

Generator Command(s)

This command can be used to generate:

  • The domain model class.
  • A repository class for the model.
  • The model's identity class as value object (optional).
  • A Doctrine database entity configuration, either as annotation or separate config file (optional).
  • A custom Doctrine type for the model's identity class (optional).
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 & Domain Events

Optionally, by inheriting from AggregateRoot, you can make a model class an aggregate root, which is used to encapsulate a group of related objects, along with the behavior and rules that apply to them. The aggregate root is usually responsible for managing the lifecycle of the objects within the aggregate, and for coordinating any interactions between them.

The AggregateRoot base class comes with some useful functionality to record and dispatch domain events, which represent significant occurrences or state changes within the domain of a software system.

Generator Command(s)

N/A

Example Usage

// 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

Hint: If you want to dispatch an event directly, use AggregateRoot::dispatch() instead of AggregateRoot::record().

If you cannot (or don't want to) extend from AggregateRoot, you can alternative use DispatchableTrait to add dispatching capabilities to any class. The former is however the recommended way.

Command & Query

You can use CommandBus and QueryBus as services to implement CQRS. Internally, both buses will use the Symfony messenger to dispatch commands and queries.

Generator Command(s)

These commands can be used to generate:

  • A command and command handler class.
  • A query and query handler class.

The query / command generated is just an empty class. The handler class is registered as a message handler for the configured 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)

Example Usage

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

        // ...
    }
}

Controller

A standard Symfony controller, but augmented with command and query bus(es).

Generator Command

This command can be used to generate a controller with optional QueryBus and CommandBus dependencies.

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

Resource

An API Platform resource, but instead of using the standard approach of using a combined entity/resource approach, it is preferred to separate model (domain layer) and API Platform specific resource (infrastructure layer)

Generator Command

Minimum required API Platform version is 2.7 for the new metadata system.

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).

geekcell/ddd-bundle 适用场景与选型建议

geekcell/ddd-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10.15k 次下载、GitHub Stars 达 12, 最近一次更新时间为 2023 年 01 月 09 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 geekcell/ddd-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 geekcell/ddd-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 geekcell/ddd-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 10.15k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 12
  • 点击次数: 6
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 12
  • Watchers: 5
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-01-09