1

我正在开始一个新项目;我希望遵循 DDD 方法。我们已经与业务部门进行了交谈,并在某些细节(互联网电视)方面获得了对该领域的一些了解。

该团队五人强大且分布广泛。我们采用了存储库模式进行数据访问。我们总体上遵循基于服务的方法;服务负责执行操作,我们将通过 REST API 公开一些操作,一些通过我们自己的客户端应用程序公开。

没有使用 ORM 经验的人(目前我也没有大量经验)希望对实体之间没有关系的实体进行建模,其理由是这迫使使用存储库的开发人员准确地知道他们的影响正在数据库上。我想指出的是,这最终会导致一组非常健谈的服务、更多需要维护和测试的代码,以及一个根本没有抓住重点的领域模型。我认为这不是一个好方法,我与之交谈过的任何人也没有。

他们对实现这种方法的渴望是存储库外观下的 Linq2SQL。这需要第二个模型,它与域模型之间的映射类/层,以及存储库中的大量重复,因为编写通用存储库似乎是不可能的(我们目前已经看到)。也无法映射利用继承的 L2S 实体(这意味着每个实体都必须具有 created-on、created-by 等属性)

第一个问题: 谁能给我一些关于如何改变主意的建议?我正在编写一个使用 NHibernate 的副项目,它当然很好地支持 DDD 方法,基于“给我看代码”是一个强有力的论点。

第二个问题: 我应该尝试在我的 NHibernate 使用我自己的时间副项目中演示什么样的事情?我是新手;他们对 NHibernate 的厌恶之一是学习曲线和对 XML 的要求;我的反驳是它是一个强大的工具,而且 Fluent NHibernate 消除了对 XML 的需求。他们还是不喜欢。

4

4 回答 4

3

你看过 DDD 中聚合根的概念吗?基本上,您只需从存储库中请求聚合根,然后加载整个聚合。聚合具有执行所需操作所需的一切,这样可以消除您对闲聊的担忧,也可以解决您的团队对明确加载内容的担忧。

在您的辅助项目中,演示基于加载整个聚合的聚合根的存储库。这是相当直接的代码,其意图非常明确。不幸的是,您仍然必须遵循 NHibernate 学习曲线,但是如果您使用这种方法,那么“魔法”就会减少。

于 2008-10-21T22:49:40.273 回答
1

因为我没有使用过休眠,所以不能给你细节。但适用于几乎所有此类情况的一般事实是:

“让一切尽可能简单,但不要更简单。”
   -  艾尔伯特爱因斯坦

所以我的意见是使用尽可能少的连接来保持系统的良好定义。并且避免尝试连接所有东西,因为它会在后面咬你(记住编程中的松散耦合原则)

于 2008-10-15T09:08:32.650 回答
1

根据您的描述,我猜您正在构建的每个服务都以特定实体为中心,当您的域模型想要不同的实体时,它需要使用不同的服务。

如果是这种情况,我会建议该服务过于细化。我建议围绕需要完成的流程为您的服务构建接口,并使用这些服务实现的域模型部分。我的理解是 SOA 提倡将系统公开为一组服务,但是单个系统的组件之间的内部交互不应该是服务。

这种方法导致了一个丰富的域模型,使用聚合根作为将实体关联在一起的一种手段和存储库的基础,服务位于这种暴露粗粒度行为之上,而不是与任何单个实体的基本交互。系统内部的客户端应用程序可以提供此功能(使用相同的域模型)。

如果模型中的实体是相关的并且这些关系对系统的行为很重要,那么应该强制执行这些关系(因此系统反映了被建模的域),如果每个实体都是独立的,这将很难做到,特别是如果它们是服务。

您最终将得到一个所有实体服务都需要相互调用的系统(创建大量耦合、增加变更管理开销等),否则您将无法强制执行这些关系,这意味着稀释您的模型并可能导致不一致的行为或丢失的数据。

这将从根本上归结为高内聚和低耦合的基本原则,它们是相反的力量,有必要在解决方案中尝试平衡它们。如果您没有关系(或隐式关系),那么您会以内聚为代价获得低耦合,并且如果确实存在未表示的关系或在更高级别增加依赖关系,则可能会产生维护问题。如果你强烈地强制执行太多的关系,你最终会导致你的领域模型变成一团泥球并且变得难以管理。这方面的具体建议很困难,但通常我会从使用聚合构建模型开始,专注于聚合内部的关系并经常查看模型。

特别是在 NHibernate 上,我建议展示它提供的简洁抽象、所需代码的减少、无需更改代码的简单配置以及提供的功能数量,例如身份映射和工作单元等。

于 2008-10-21T23:29:43.810 回答
0

看来您的团队正在使用 ORM 只是将数据库映射到一组具体类的一种方式,以使代码更好一些。如果您想创建一个域模型而不仅仅是一个抽象的数据库模型,那么很明显您应该包含关系。如何在幕后加载数据是另一回事。

于 2008-10-21T23:13:21.520 回答