kuaukutsu/ds-dto

此包已被废弃且不再维护。未建议替代包。

数据结构:DTO(数据传输对象)

2.0.2 2023-10-27 13:23 UTC

This package is auto-updated.

Last update: 2024-05-29 20:49:42 UTC


README

免责声明:我只是发表自己的看法,并不保证其真实性,但我会尽量表达(大致内容)。

术语表

  • 表单 从外部获取数据(请求:POST/GET/ARGS/数组),处理(验证、过滤),传递到服务层(业务逻辑)。
  • 模型 系统中的某种数据对象表示(基础设施、仓库)。
  • 服务 各种服务(UoW、UseCase),处理业务逻辑。
  • DTO 传输,加上数据方案(注释可能说明数据如何和在哪里使用)。有快速组织数据版本化的能力。

描述示例的方案

在最简单的实现中,得到以下方案

interface Form extends Dtoable
{
    /**
     * Конвертирует объект в массив.
     *
     * @param string[] $fields поля которые должны быть в исходном массиве
     * @return array<string, mixed>
     */
    public function toArray(array $fields = []): array;
    
    /**
     * Форма содержит данные, их нужно передать в сервис (например, Service). 
     *
     * @param class-string $dtoClassName
     */
    public function toDto(string $dtoClassName): DtoInterface;
}
interface Model 
{
    public function fromDto(DtoInterface $dto): self;
}
interface Service 
{
    public function save(DtoInterface $dto): bool;
}

示例 DTO

方法可能不同,但我个人不喜欢通过构造函数传递数据,可能随着PHP 8和命名参数的出现,我会改变观点。

/**
 * @psalm-immutable
 */
final class ModelDto extends BaseDto
{
    public int $id;

    public string $name;

    /**
     * nullable в данном случае говорит что значение при Инициализации объекта может быть незадано.
     */
    public ?array $props = [];
}

DTO 中可以使用 protected 属性(以及获取器),这样就不会有想要通过其他方式填充它们的愿望,除了通过 hydrate()。关键是 不可变性 和没有逻辑,一旦这里出现逻辑,它就立即变成 实体,或者可能是某种其他类型的 值对象

可能会有人问,为什么这里需要DTO,因为可以直接将表单传递到服务层($form或以数组形式$form->toArray()),同样也可以直接从服务层获取模型。关键在于,模型,就像表单一样,是某种逻辑的实现,而在应用程序中可能有多个组件,这些组件根据BL的要求,以自己的方式实现逻辑。因此,需要一个机制,允许三个不同的表单使用同一个方法,比如$service->save(DTO)。另外,因为表单就像任何其他对象一样,可以改变自己的状态,而且没有明确保证数据的不变性。

class Service 
{
    public function save(DtoInterface $dto): bool
    {
        $data = $dto->toArray();

        ...
    
        return true;
    }
}

Docker

docker pull ghcr.io/kuaukutsu/php:8.1-cli

容器

  • ghcr.io/kuaukutsu/php:${PHP_VERSION}-cli默认
  • jakzal/phpqa:php${PHP_VERSION}

shell

docker run --init -it --rm -v "$(pwd):/app" -w /app ghcr.io/kuaukutsu/php:8.1-cli sh

测试

单元测试

该包使用PHPUnit进行测试。要运行测试

make phpunit

静态分析

代码使用Psalm进行静态分析。要运行静态分析

make psalm

代码规范

make phpcs

Rector

make rector