c# - 领域驱动设计 API 问题

标签 c# .net domain-driven-design

我是 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/

相关文章:

c# - 从列表值创建对

c# - 在局部变量 C# 上声明字符串的局部常量有什么好处

java - DDD、JPA 和多模块 Maven

domain-driven-design - 洋葱架构中的资源文件放在哪里?

c# - Entity Framework 4 : How to turn a string into an object for . OrderBy(p => p.fieldname)?

c# - Windows 7 上的端口转发

c# - 寻找领域事件的例子

c# - 将现有的 Node Js 项目添加到现有的 .Net 解决方案

c# - 在控件上使用 DoubleBuffer 的优缺点

nhibernate - nhibernate 的双向关系模式