域驱动设计(DDD)的有用工具。

v2.1.20 2024-09-24 12:08 UTC

README

根据域驱动设计(DDD)构建应用程序的有用类集合。

目录

基本域类

DTO

所有域对象的基类是 DTO。DTO 允许在我们的类中嵌入属性(如JAVA、C# 和一些其他严格类型的程序语言)。一个类属性由三个元素组成

  1. 私有或受保护的类字段。
  2. 根据 PHPDoc (@property) 在类注释中的属性描述。
  3. 可选的设置器或获取器。

DTO 是一个抽象类。它有两个子类:StrictDtoWeakDto。它们之间的区别是,如果属性不存在,第一个在类初始化期间抛出 NonExistentPropertyException,而第二个不会。

DTO 使用示例

/**
 * @property string $prop1
 * @property-read DateTime $prop2
 * @property-write int $prop3
 */
class Data extends StrictDto
{
    private $prop1;
    private DateTime $prop2;
    protected int $prop3 = 0;
    
    public function setProp1(string $value): void
    {
        $this->prop1 = $value;
    }
    
    protected function setProp2(?DateTime $value): void
    {
        $this->prop2 = $value;
    }
    
    public function getProp2(): array
    {
        return $this->prop2 ?: new DateTime();
    }
}

$dto = new Data([
    'prop1' => 'abc',
    'prop2' => null,
    'prop3' => 10,
    'prop4' => 1 // causes NonExistentPropertyException for StrictDto but not for WeakDto.
]);

$val1 = $dto->prop1; // abc
$val2 = $dto->prop2; // current time object
$dto->prop3 = 100;
$val3 = $dto->prop3  // throws RuntimeException
$dto->prop4 = 1      // throws NonExistentPropertyException

$dtoAsArray = $dto->toArray(); // you can use toNestedArray() if some properties are DTO themselves.
$dtoAsJson = json_encode($dto); // or use $dto->toJson()
$dtoAsString = (string)$dto // or use $dto->toString() 

有一些规则可以使属性正常工作

  • PHPDoc 注释中的属性类型无关紧要。要限制属性类型,您需要为属性设置器、获取器或字段指定类型提示。如果分配的值与属性类型不匹配,将抛出 InvalidArgumentException
  • 只读或常规属性的获取器必须是公共的。
  • 只写或常规属性的设置器必须是公共的。
  • 私有和受保护的设置器在类初始化期间自动调用。
  • 如果您想继承属性,其字段和设置器不能是私有的。

域对象

DomainObject 是所有域对象的基类。它继承自 StrictDto。所有域对象都包含一些有用的方法

  1. equals() 用于比较域对象与其他对象。
  2. copy() 用于创建域对象的副本。
  3. copyWith() 用于创建具有给定属性值的域对象的副本。
  4. hash() 用于获取唯一的域对象哈希值。
  5. domainName() 用于获取域对象的名称(默认情况下等于类名称)。

值对象

ValueObject 是所有域值对象的基类。它具有与 DomainObject 相同的方法。

SQL 构建器

SQL 构建器是一个简单的包装器,允许为某些特定的关系数据库管理系统(目前仅支持MySQL和PostgreSQL)构建 SQL 查询字符串。您可以使用它来独立于任何 PHP 框架。请参阅下表了解如何使用 SQL 构建器。

MySQL

选择查询

PHP 表达式

$row = (new SelectQuery($queryExecutor))
    ->from('users', 'u')
    ->where('u.id', '=', 10)
    ->row();
    
// $row is a single record (associative array) or empty array.

执行的 SQL 查询

SELECT * FROM users u 
WHERE u.id = 10

PHP 表达式

$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->select([
        'id',
        'firstName',
        'lastName',
        'email'
    ])
    ->where('email', 'LIKE', '%gmail.com')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array. 

执行的 SQL 查询

SELECT id, firstName, lastName, email FROM users 
WHERE email LIKE '%gmail.com'

PHP 表达式

$rows = (new SelectQuery($queryExecutor))
    ->from([
        'users' => 'u,
        'contacts' => 'c'
    ])
    ->select([
        'u.id' => 'user_id',
        'c.id' => 'contact_id'
    ])
    ->where('c.user_id = u.id')
    ->limit(10)
    ->offset(50)
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

执行的 SQL 查询

SELECT u.id user_id, c.id contact_id FROM users u, contacts c 
WHERE c.user_id = u.id 
LIMIT 10 OFFSET 50

PHP 表达式

$rows = (new SelectQuery($queryExecutor))
    ->from('users', 'u)
    ->from('contacts', 'c')
    ->select('u.id', 'user_id')
    ->select('c.id', 'contact_id')
    ->where('c.user_id = u.id')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

执行的 SQL 查询

SELECT u.id user_id, c.id contact_id FROM users u, contacts c 
WHERE c.user_id = u.id

PHP 表达式

$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->orderBy('email', 'DESC')
    ->orderBy('id', 'ASC')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

执行的 SQL 查询

SELECT * FROM users
ORDER BY email DESC, id ASC 

PHP 表达式

$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->leftJoin('contacts c', 'c.user_id = u.id')
    ->where('u.id', '=', 5)
    ->count('DISTINCT c.name');
    
// $count is an integer value.

执行的 SQL 查询

SELECT COUNT(DISTINCT c.name) FROM users u
LEFT JOIN contacts c ON c.user_id = u.id
WHERE u.id = 5

PHP 表达式

$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->innerJoin('contacts c', 'c.user_id = u.id')
    ->select([
        'u.id', 
        'u.email'
    ])
    ->select('COUNT(c.id)', 'contact_number')
    ->groupBy('u.id')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

执行的 SQL 查询

SELECT i.id, u.email, COUNT(c.id) contact_number FROM users u
INNER JOIN contacts c ON c.user_id = u.id
GROUP BY u.id

PostgreSQL