13

问这个问题的原因是我一直想知道如何将所有这些不同的概念拼接在一起。有很多关于 DDD、依赖注入、CQRS、SOA、MVC 的示例和讨论,但没有太多关于如何以灵活的方式将它们组合在一起的示例。

我的目标:

  1. 开发只需很少或无需修改即可独立运行的模块
  2. 更改或修改 UI 应该尽可能简单(即 UI 应该尽可能少做,并且要“愚蠢”
  3. 使用记录在案的模式和原则

为了更容易提出具体问题,主要架构现在如下所示:

员工管理示例

该示例显示如何向员工添加注释。员工管理是一种有界上下文。Employee 有几个属性,其中一个ICollection<Note>.

在我的理解中,绑定上下文是分隔代码的逻辑位置。每个 BC 都是一个模块。大多数时候,如果需要,我发现他们每个人都可以保证自己的 UI(即某些模块可能可用于 Windows 手机)。

包含所有业务逻辑。

基础设施包含存储库实现,以及发送邮件、保存文件和不属于域的实用程序的服务。我正在考虑制作一些我必须在多个域(如发送电子邮件)中使用的通用服务功能,作为一种 API,我可以引用它来保存一些跨多个 BC 实现相同事物的代码。

查询层包含除 GetById 之外的所有查询,我需要在存储库中获取对象。查询层可以查询其他持久性实例,并且可能需要为每个 UI 更改一些。

Wcf 或 Web Api 是我的应用程序层,它可能属于基础设施而不是外部。该服务还设置了依赖关系,因此 UI 需要做的就是询问信息并发送命令。

该过程从蓝色箭头开始。阅读模型,因为它包含大部分信息。

在第 1 步中,此示例中的 EmployeeDto 只是一些员工属性,用于向用户显示他们需要记录的员工的用户信息(例如关于新体验的注释或类似内容)。

所以,问题是:

  1. 实现这样的分层架构真的涉及这么多映射,还是我错过了什么?
  2. 是否建议(甚至智能)使用 Wcf 服务来运行这样的主逻辑(它实际上是我的应用程序服务)
  3. 如果我的 UI 层中没有我的域对象,是否有 Wcf 的替代品?
  4. 这个实现有什么问题吗。有什么需要注意的坠落坑?

  5. 你有什么好的例子可以推荐看,可以帮助我理解所有这些概念应该如何协同工作。

更新: 我现在已经阅读了大部分文章(相当多的阅读),除了付费书籍(需要更多时间做)。它们都是非常好的指针,将 Wcf 更多地视为适配器的方式似乎是对问题 2 的一个很好的回答。如果我打算走那条路,JGauffins 在他的框架上的工作也很有趣.

然而,正如下面的一些评论中提到的,我觉得一些例子倾向于推荐或实现事件和/或命令源、消息总线等。对我来说,现在就计划这种级别的扩展是过大的。与许多业务应用程序一样,这是一个“大量”(就内部应用程序而言,认为最多几千个)用户处理大量数据,而不是需要实现事件和命令的高度协作域队列通常与 CQRS 相关联以应对这种情况。

根据下面的答案,我将开始使用的方法将基于上面的模型和这样的答案:

  1. 我只需要处理映射。利大于弊。

  2. 我会将应用程序服务拉回基础架构,并将 Wcf 视为“适配器”

  3. 我将使用命令对象并发送到应用程序服务。不要用域对象污染我的域。

  4. 为了降低复杂性,我现在尝试在没有事件/命令来源、消息总线等的情况下进行管理。

此外,我只想链接到Udi Dahan关于 CQRS的这篇博客文章,我认为这样的事情可以降低复杂性,除非真的需要它们。

4

2 回答 2

10
  1. 映射和图层之间存在权衡。存在某些映射的原因之一是适当的抽象不可用或不可行。因此,在层之间进行显式映射通常比尝试实现推断映射的框架更容易,但我离题了;这取决于对这个问题的哲学讨论。

  2. WCF 或 WebAPI 服务应该非常精简。将其视为六边形架构中的适配器。它应该将所有内容委托给应用程序服务。术语服务的混淆会导致混淆。总体而言,WCF 或 WebAPI 的目标是使您的域“适应”特定技术,例如 HTTP。WCF 可以被认为是在 DDD 术语中实现了一个开放的主机服务。

  3. 您提到了 WebAPI,如果您想要 HTTP,它是一种替代方法。最重要的是,要意识到这个适配层的作用。正如您所说,最好让 UI 依赖于 DTO,并且通常是使用 WCF 或 WebAPI 或其他任何东西实现的服务合同。这使事情变得简单,并允许您在不影响开放主机服务的消费者的情况下改变域的实现。

  4. 您应该始终注意不必要的复杂性。分层是一种权衡,有时它可能是矫枉过正的。例如,在一个主要是 CRUD 的应用程序中,没有必要分层这么多。此外,如上所述,不要将 WCF 服务视为应用程序服务。相反,请将它们视为传输技术和应用程序服务之间的适配器。反过来,将应用程序服务视为域的外观,无论您的域是使用 DDD 还是事务脚本方法实现的。

  5. 真正帮助我理解的是关于六边形架构的参考文章。这样,您可以将您的域视为核心,并围绕它进行分层,使您的域适应基础架构和服务。你所拥有的似乎已经遵循了这些原则。Vaughn Vernon 的《实现领域驱动设计》是一个很好的、深入的资源,特别是关于架构的章节。

于 2012-11-27T21:30:20.810 回答
2

实现这样的分层架构真的涉及这么多映射,还是我错过了什么?

是的。问题是它不是同一个对象。它是同一对象的不同表示,但专门针对每个用例。视图模型包含更新 GUI 的逻辑,DTO 专门用于传输(可能会被规范化以简化传输)。等等等等。它们可能看起来一样,但实际上并非如此。

您当然可以尝试将所有的修改都放在一个类中,但是当您的应用程序增长时,使用它不会很有趣。

是否建议(甚至智能)使用 Wcf 服务来运行这样的主逻辑(它实际上是我的应用程序服务)

你需要某种网络层。我不会让所有客户端应用程序都接触我的数据库。如果您弄乱了数据库模式(如果某些客户端仍在运行旧版本),它将造成维护噩梦。

通过使用服务器,维护版本差异要容易得多。

请注意,一旦使用 WCF 服务定义,就应将其视为常量。任何更改都应在新接口中定义(例如MyService2)。

如果我的 UI 层中没有我的域对象,是否有 Wcf 的替代品?

你可以看看我的框架。开始发帖:http: //blog.gauffin.org/2012/10/writing-decoupled-and-scalable-applications-2/

这个实现有什么问题吗。

不是我能看到的。看起来你已经很好地掌握了这些概念以及应该如何使用它们。

有什么需要注意的坠落坑?

不要试图对查询和命令偷懒。不要让它们更通用以适应多个用例。当应用程序增长时,它会回来咬你。较小的类更容易维护。

你有什么好的例子可以推荐看,可以帮助我理解所有这些概念应该如何协同工作。

我链接的博客文章和该系列中的所有其他文章。

于 2012-11-28T16:18:37.727 回答