kuaukutsu / ds-dto
此包已被废弃且不再维护。未建议替代包。
数据结构:DTO(数据传输对象)
2.0.2
2023-10-27 13:23 UTC
Requires
- php: ^8.1
- kuaukutsu/ds-collection: ^2.0.2
- yiisoft/arrays: ^3.0
- yiisoft/strings: ^2.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.13
- icanhazstring/composer-unused: ^0.8
- phpunit/phpunit: ^9.5
- rector/rector: ^0.18
- roave/infection-static-analysis-plugin: ^1.3
- roave/security-advisories: dev-latest
- slevomat/coding-standard: ^8.7
- squizlabs/php_codesniffer: ^3.7
- vimeo/psalm: ^5.15
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