2

http://i.stack.imgur.com/YZXZN.png(我目前不允许嵌入图像)

我真的可以对上面的班级模型使用一些帮助。我很惭愧地说,我是“那些”在大学学习面向对象、编写考试、取得优异成绩但从未着手在我的真实世界代码中实施这些原则的开发人员之一。在开始编写应用程序设计之前,我从未真正坐下来考虑过它。因此,在单一的遗留银行应用程序开发和维护的重压下,我的设计和编码技能一直在慢慢消亡和停滞不前。经过多年的努力,我决定是时候做出改变了!我一直在深入研究设计模式、DDD、NoSQL、DI 等领域。过去两周对我来说是一段非常紧张的经历,有时我想我在为大公司和银行工作时错过的大量最佳实践和技术几乎让我流下了眼泪。我简直不敢相信这么长时间以来我与尖端技术和良好的设计方法相距甚远,而突然发生的所有事情都可能使我陷入编码瘫痪状态!我根本无法开始编码,因为我觉得我的设计需要更多调整,或者我需要对特定主题进行更多研究。不过,够了,我需要继续努力,至少对项目进行第一次迭代。突然出现的所有事情都威胁到我进入编码瘫痪状态!我根本无法开始编码,因为我觉得我的设计需要更多调整,或者我需要对特定主题进行更多研究。不过,够了,我需要继续努力,至少对项目进行第一次迭代。突然出现的所有事情都威胁到我进入编码瘫痪状态!我根本无法开始编码,因为我觉得我的设计需要更多调整,或者我需要对特定主题进行更多研究。不过,够了,我需要继续努力,至少对项目进行第一次迭代。

无论如何,足够的戏剧,关于我的问题:

我已经开始为我的高尔夫应用程序创建模型。想在一定程度上坚持 DDD,也想利用 NoSQL (RavenDB),我开始提出以下要求。

  • 我的平台堆栈是 Windows / IIS / MVC 3.0 / RavenDB
  • 我需要找到我的总根!我已经着手将它们定义为我的系统中唯一能够以自己的方式持续存在的元素。其他一切我都简单地认为是聚合的“子组件”。请注意,尚未定义实际行为。
  • 我的聚合根将是唯一真正保留在我的 RavenDB 文档存储中的类,它们将“按原样”保留。就实现的性能优势而言,拥有大型树状类结构似乎是 RavenDB 的最佳情况。
  • 我觉得不需要存储库层(一直在关注 Ayende 的一些帖子),因为 RavenDB API 感觉流畅且非常轻量级。如果需要,我将通过控制器上的自定义操作属性简单地打开和关闭我的会话。我已经看到如果没有存储库层测试可能会很棘手,但我肯定应该能够简单地模拟一些“内存中”域对象吗?
  • 对数据库的写入将发生在单独的服务层中
  • 有一次我停下来问自己:“我到底要把我的领域行为放在哪里!?”。搜索网络的普遍共识似乎表明我应该让我的域(实体)没有任何行为(业务逻辑),并将其全部在我的服务层中处理。但是在阅读了一些 Eric Evans 之后,我确信我的域行为应该存在于那里......在域中!

问题 - 作为 DDD 和建筑设计领域的真正菜鸟,我至少是在正确的轨道上,还是注定要毁灭?- 任何想法、警告、建设性的批评和对上述内容的见解将不胜感激!

4

3 回答 3

3

为了应对这一切过于学术化并在分析中停留太久:首先让它发挥作用。然后让它变得漂亮。

尽可能将行为放在数据附近。使用无法明确地为类分配职责的服务(例如,“转账”方法是否应该在 SavingsAccount 类上?)。服务可以是聚合的一部分。

一定要使用存储库(我不同意 Ayende)。您提到使用单独的服务层进行数据库写入。Repository 是一个完美的接口,可以将该层放在后面。这也是一个完美的测试接缝。

没有彻底查看您的类图,但您可能在这里和那里过度使用继承。优先组合而不是继承。继承可以很快地抬起它丑陋的脑袋。

在选择聚合根时,一个重要的标准是生命周期。当聚合根死亡时,聚合中的其他所有内容也会死亡。聚合根也在控制之中,聚合之外的一切都通过它。如有疑问,只需创建很多(单个实体聚合)。使用文档数据库,您通常会为每个聚合存储一个文档,因此这与您选择它们​​的方式有些匹配。存储对不同聚合的引用的 ID。

于 2012-05-12T03:15:28.860 回答
0

所以,是的,进入兔子洞不会在短期内提高你的生产力,但从长远来看可能会帮助你成为一名成熟的开发人员。DDD、NoSQL 等有很多东西,你可以花几年时间学习。

如果你希望你的下一个项目成功,我的建议是坚持你所知道的,并逐步引入新技术,这样你就可以始终感到完全掌控,而不是依赖于某人必须忍受的“最佳实践”你。

于 2012-05-12T02:24:22.893 回答
0

首先,我要祝贺您决定采取措施尝试变得更加专业。我对这个行业缺乏专业感到绝望,有时觉得我走在 80% 的牛仔/黑客和 20% 的专业人士之间。

对于你的问题:

  • 你读过Vaughn Veron 的这篇文章吗?如果没有,你应该。它为设计聚合提供了极好的指南,我认为它的复杂性被低估了。
  • 查看您的模型,我不确定您是否真的定义了聚合?我可以看到您已经确定了聚合,但是聚合应该有明确的边界并且与其他聚合分开(即没有引用其他聚合根的实体,让它们引用它们的 ID)。属性名称RefereeUserIDList 暗示您实际上正在这样做,但图表显示它持有对实际“用户”聚合根的引用?
  • 在识别聚合、根和模型设计方面,我认为我们不能在这里为您提供帮助,因为这完全取决于行为要求。不过我会说:尝试将您的设计基于行为,而不是数据结构。这是一个很难转变的心态,但尽量不要描绘数据库结构。
  • 我还没有读过 Ayende 所说的关于存储库的内容,但只要你可以模拟 Raven API(我假设你可以给他制作 Rhino 模拟),那么这应该不是问题。
  • 可能最重要的是,不要将所有领域逻辑都放入服务层。你最终会得到一个贫血域模型,它是相当于敌基督的 DDD。
  • 就个人而言,在学习 DDD 时,我理解了所有的原则,但在尝试将理论转化为实践时却遇到了困难。如果我说实话,我会说我只是因为我了解了与 DDD 互补的校长CQRS才真正成功。我真的建议您观看Greg Young的一些关于该主题的视频。
于 2012-05-18T12:52:43.530 回答