我是 DDD 的新手,我正在处理我的第一个项目,这是一个在线高尔夫郊游注册流程。我的要求很简单。用户注册郊游并可以选择添加四人组。他们也可以赞助一个带有消息和其他一些东西的洞,但我想先散列一下我们的四人组的东西。
因此,我的第一个聚合包含一个注册实体、四个值对象(其中包含一个团队名称和 4 个玩家值对象)。
在设计api时,我想到了以下伪代码:
Registration reg = new Registration();
Foursome foursome = reg.CreateFoursome("My Team");
foursome.Player1.Assign("John Doe", 5, ShirtSize.XL);
reg.Register();
我的问题是,聚合的内部组件之一正在暴露给客户端代码,所以我是否要公开自己的问题?这种简单的设计或替代 API 有什么缺陷吗?
任何帮助都会很棒,因为我现在处于分析瘫痪状态!
谢谢
最佳答案
让我们从聚合 definition 开始:
A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the Aggregate, designated as the root. A set of consistency rules applies within the Aggregate's boundaries.
聚合是一组您不希望多个用户同时编辑的对象,因为它会破坏域不变量。聚合也是一个生命周期单元。如果不知道这些不变性、一致性和生命周期规则是什么,就很难回答您的问题。在同一个注册上创建两个 Foursomes 会很糟糕吗?未分配 Player1 的 Foursome 是否无效/不一致?在 Registration 对象上调用 Register 不会“破坏”它吗?如果其中一个答案是正确的,那么您不应该那样公开您的对象。此代码应隐藏在您的聚合中。
看起来 Foursome 也不是 Value Object因为它是可变的。它可能是一个应该受注册聚合根保护的实体。
// PlayerInfo is a value object
public static Registration CreateNew(String foursomeName, PlayerInfo player1, ...) {
if (foursomeName == null) {
throw new ArgumentNullException("foursomeName");
}
if (player1 == null) {
throw new ArgumentNullException("player1");
}
Registration reg = new Registration();
Foursome foursome = reg.CreateFoursome("My Team");
foursome.Player1.Assign(player1);
if(player2 != null) {
foursome.Player2.Assign(player2);
}
reg.Register();
// return consistent and valid Registration instance
return reg;
}
同样,这可能不是您想要的,它实际上取决于您的领域模型。也许您的聚合根应该是像 FoursomeRegistartion 这样的实体。如果玩家可以存在于四人组/注册边界之外,也许他们自己就是聚合体。正如其他人所说,很难在第一次就获得正确的模型。进行首次实现并不断重构。
关于c# - 领域驱动设计 API 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7210795/