热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP深度解析:聚合与事件溯源

本文深入探讨了领域驱动设计(DDD)中的聚合概念及其在事件溯源架构中的应用。聚合是一组紧密相关的类,这些类作为一个整体运作,形成一个有明确边界的组织。只有通过聚合根才能与聚合内的对象进行交互。

本文讨论了领域驱动设计(DDD)中的关键概念——聚合,以及它在事件溯源架构中的角色。作为DDD战术设计的重要组成部分,理解聚合对于构建复杂系统至关重要。


聚合是指一组紧密相关的类,它们作为一个整体运作,形成一个具有明确边界的组织。边界内的对象只能通过聚合根(Aggregate Root)与外界交互。聚合不同于通用集合(collection),后者是一个更广泛的概念,而聚合则特定于领域模型。


实体


实体用于建模独立的事物,每个实体都有一个唯一的标识符,如ID、UUID或用户名等。实体通常是可变的,其状态随时间变化。在DDD中,ORM模型中的Model可以视为实体。例如,数据库中的每条记录都有自己的ID,记录的内容也会发生变化。


class User extends Model
{
private int $id;

public function __construct(int $id)
{
$this->id = $id;
}

public function changePassword(string $password)
{
// 领域逻辑
}
}

$user = new User(1);
$user->changePassword('new_password');

值对象


值对象用于描述、量化或测量实体。与实体不同,值对象没有唯一标识符,且是不可变的。一旦创建,值对象的属性就不能更改。如果需要修改值对象的状态,应创建一个新的值对象。


无标识符性

值对象不应具有如ID、UUID等标识符。


不可变性

值对象创建后,其值不能被修改。在定义值对象时,应避免提供修改其内部属性的方法。如果需要变更方法,该方法应返回一个新的值对象实例。


class Money
{
private int $amountInCent;
private string $currency;

public function __construct(int $amountInCent, string $currency)
{
$this->amountInCent = $amountInCent;
$this->currency = $currency;
}

public function getAmountInCent(): int
{
return $this->amountInCent;
}

public function getCurrency(): string
{
return $this->currency;
}

public function add(Money $money): Money
{
if ($this->currency !== $money->getCurrency()) {
throw new \Exception('不能添加不同货币');
}
return new Money(
$this->amountInCent + $money->getAmountInCent(),
$this->currency
);
}
}

可替换性

由于值对象的不可变性,如果两个值对象的值相等,则它们可以互换使用。例如,两张10元人民币可以互换而不引起任何问题。


许多领域模型可以使用值对象来建模,这提供了安全和灵活的代码管理方式。例如,密码可以使用值对象来实现,确保其有效性和安全性。


class Password
{
private string $value;

public function __construct(string $value)
{
$this->guard($value);
$this->value = $value;
}

public function toString(): string
{
return $this->value;
}

private function guard(string $value)
{
if (empty($value)) {
throw new \Exception('无效的密码值');
}
}
}

$user = new User(1);
$password = new Password('secure_password');
$user->changePassword($password);

初始化后的密码对象肯定是有效的,因为我们在构造函数中进行了验证。这为后续代码提供了安全保障。


聚合根


聚合根本质上是一个实体,但它在聚合中扮演特殊角色,作为聚合对外的唯一接口。可以将聚合比作一个家庭户口簿,聚合根则是户主,所有操作都需要通过户主进行。


领域事件


领域事件是指领域中与业务直接相关的事件,与基础设施和代码框架无关。因此,领域事件不应是像EmailSent或RecordUpdated这样的通用框架事件。领域事件在聚合根中生成,并持久化存储,以确保所有事件的正确性。如果有任何异常,领域事件不会被错误地保存。


总结


在事件溯源架构中,聚合由一个聚合根和一个或多个上述部分组成。通过理解和应用这些概念,可以更好地设计和实现复杂的业务系统。


本文转载自【何以解耦】:原文链接,如果你对TDD、DDD和简洁代码感兴趣,欢迎关注公众号【何以解耦】,一起探索软件开发之道。


推荐阅读
author-avatar
小怡的宝_594
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有