作者:小怡的宝_594 | 来源:互联网 | 2024-11-25 11:43
本文深入探讨了领域驱动设计(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和简洁代码感兴趣,欢迎关注公众号【何以解耦】,一起探索软件开发之道。