biberlabs / ddd-embeddables
一组可重用的值对象集合,可随时用作Doctrine实体的嵌入对象
v0.2.0
2022-10-10 20:22 UTC
Requires
- php: ^8.0
- composer-runtime-api: ^2
- doctrine/orm: ^2.11
Requires (Dev)
- phpunit/phpunit: ^9.5
Suggests
- ext-gmp: Calculate without integer limits
- ext-intl: Format Money objects with intl
This package is not auto-updated.
Last update: 2024-09-20 21:49:39 UTC
README
这是一个PHP编写的可重用值对象集合,适用于8.0及以上版本。值对象是领域驱动设计(DDD)方法的基本构建块,由Martin Fowler在《企业应用架构》第486页的P部分中描述如下:
"值对象是一个小型简单对象,如货币或日期范围,其等价性不是基于身份。"
—— Martin Fowler
此库中所有类均注解为ORM\Embeddable
,并适当调整了列属性。这使得它们可以在任何使用Doctrine ORM的项目中作为嵌入对象使用。
安装与使用
使用composer安装此库。
$ composer require biberlabs/ddd-embeddables
然后在您的实体中使用它
<?php namespace MyApp\Entity; use Doctrine\ORM\Mapping as ORM; use DDD\Embeddable\EmailAddress; /** * @ORM\Entity */ class User { /** * @ORM\Embedded(class="DDD\Embeddable\EmailAddress") */ private $email; // Returns an EmailAddress instance, not a string public function getEmail(); // Use type-hinting if you need a setter public function setEmail(EmailAddress $email); }
之后,您可以根据需求编写自定义的DQL查询,同时访问值对象的属性,例如
SELECT u FROM User u WHERE u.email = :email -- OR SELECT p FROM Payments p WHERE p.total.currency = :currency SELECT p FROM Payments p WHERE p.total.amount > 1000 -- OR SELECT u FROM User u WHERE u.name.surname = :surname SELECT u FROM User u WHERE u.name.title = :title
值对象使我们能够编写更干净、更易读的规则,以处理应用程序范围内的领域规则。例如
$username = $user->getEmail()->getLocalpart();
或
$blacklist = ['spam4me.io', 'foo.com']; if(in_array($user->getEmail()->getDomain(), $blacklist)) { // ... }
甚至
if($company->hasMap()) { $latLng = $company->getAddress()->getGeoPoint()->toArray(); //.. } class Company { // ... /** * Returns a boolean TRUE if the geolocation of the company is known, * FALSE otherwise. * * @return bool */ public function hasMap() { return $this->getAddress()->getGeoPoint() !== null; } }
运行测试
您可以通过以下命令在本地运行单元测试
$ composer test
在创建PR之前,请确保所有测试都是绿色的。
PHPUnit 9.5.25 #StandWithUkraine
................................................................. 65 / 75 ( 86%)
.......... 75 / 75 (100%)
Time: 00:00.037, Memory: 6.00 MB
OK (75 tests, 124 assertions)
贡献
如果您想为ddd-embeddables做出贡献并使其变得更好,您的帮助非常受欢迎。
在创建pull request之前,请查看我们的CONTRIBUTING.md。
进一步阅读
您对领域驱动设计感兴趣吗?以下是一些深入了解的好资源。
- 值对象 - Martin Fowler
- 使用嵌入对象分离关注点 - Doctrine ORM文档
- PHP中的领域驱动设计 - Leanpub 380页电子书。
- Aggregate Componenet模式实战 - 2009年的一篇好文章
- ZF2中的领域驱动设计概念 - Oleg Krivtsov于2014年撰写的一篇文章
- 领域驱动设计快速入门 - InfoQ的快速阅读迷你书和DDD基础介绍。