如何使用DDD和SRP实现可维护和松散耦合的应用程序?

cfs*_*cfs 13 c# architecture wcf design-patterns domain-driven-design

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

我的目标:

  1. 开发很少或没有修改的模块可以独立存在
  2. 更改或重新设计UI应该尽可能简单(即UI应该尽可能少,并且是"愚蠢的"
  3. 使用记录的模式和原则

为了更容易提出具体问题,主要的架构现在看起来像这样:

员工管理示例

该示例显示如何向员工添加注释.员工管理是一个有限的背景.员工有几个属性,其中包括ICollection<Note>.

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

Domain拥有所有业务逻辑.

基础结构包含存储库实现,以及用于发送邮件,保存不属于域的文件和实用程序的服务.我正在考虑制作一些常见的服务功能,我必须在几个领域(例如发送电子邮件)中使用它作为一种API,我可以参考这些API来保存一些代码在几个BC中实现相同的功能.

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

Wcf或Web Api是我的应用层,它可能属于基础设施,而不属于外部.此服务还设置依赖项,因此所有UI需要做的是询问信息并发送命令.

该过程从蓝色箭头开始.阅读模型,因为那里有大部分信息.

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

所以,问题是:

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

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

更新: 我现在阅读了大部分文章(相当多的阅读),除了付费书(需要更多时间).所有这些都是非常好的指针,并且更多作为适配器的Wcf的思考方式似乎是对问题2的一个很好的答案.如果我计划走这条路线,JGauffins对他的框架的工作也很有意思.

但是,如下面的一些评论所述,我觉得有些例子倾向于推荐或实施事件和/或命令源,消息总线等.对我来说,现在规划这种级别的扩展是不合适的.对于许多业务应用程序而言,这是一个"大型"(就内部应用程序而言,最多可以考虑几千个)处理大量数据的用户数量,而不是需要实现事件和命令的高度协作域队列经常与CQRS联系以应对.

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

  1. 我只需要处理映射.Thoe pros胜过缺点.

  2. 我将应用程序服务拉回到基础架构并将Wcf视为"适配器"

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

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

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

eul*_*rfx 10

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

  2. WCF或WebAPI服务应该非常薄.将其视为六边形体系结构中的适配器.它应该将所有内容委托给应用程序服务.服务一词存在混淆,导致混淆.总的来说,WCF或WebAPI的目标是将您的域"适应"到特定的技术,如HTTP.可以将WCF视为在DDD术语中实现开放主机服务.

  3. 您提到了WebAPI,如果您需要HTTP,它是另一种选择.最重要的是,要注意这个适应层的作用.正如您所述,最好让UI依赖于DTO,通常是使用WCF或WebAPI或其他任何东西实现的服务合同.这使事情变得简单,并允许您改变域的实现,而不会影响开放主机服务的使用者.

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

  5. 真正帮助我理解的是关于六边形体系结构的参考文章.通过这种方式,您可以将您的域视为核心,并将您的域分层,使您的域适应基础架构和服务.你所拥有的似乎已经遵循这些原则.所有这一切的深入资源都是Vaughn Vernon 实施领域驱动设计,特别是关于架构的章节.