放弃DDD,但需要一些好处

Bob*_*y B 19 asp.net-mvc domain-driven-design entity-framework poco

我放弃了传统的DDD,这通常是一个巨大的时间,并迫使我做无尽的映射:data layer <--> domain layer <--> presentation layer.

即使是一个小小的改变,我必须改变数据模型,领域模型,表示模型/视图模型,然后是存储库,经理/服务类,当然还有AutoMapper映射,然后测试整个事情!每次调用都需要调用一个层,该层调用一个调用底层代码的层.除了"你将来可能需要它"之外,我得不到任何回报.咩.

我目前的做法更务实:

  • 我不再担心"数据层"和"域层"之间的区别,因为没有意义 - 这些术语是可以互换的.我让EF做它的事情,并在需要时在顶部添加接口和存储库.
  • 我已经合并了我的"数据"和"域"项目(变成"核心",无聊的名字,我知道),我几乎可以发誓Visual Studio实际上运行得更快.
  • 我允许EF实体在堆栈中上下移动,但是,我仍像往常一样将它们映射到表示模型/视图模型.
  • 对于简单的操作,我直接从控制器调用存储库,对于复杂的操作,我像往常一样使用域管理器/服务; 存储库永远不会暴露IQueryable.
  • 我将实体/ POCO定义为部分类,因此我可以在相应的部分类中单独添加域行为.

问题:我现在使用遍布各处的实体,因此客户端代码可以看到它们的导航属性.并且模型在离开存储库后始终具体化,因此这些导航属性通常为空.

可能的解决方案:
1.与之共存.它很丑,但比上面解释的问题更好.
2.对于每个实体,定义一个隐藏导航属性的接口; 并使客户端代码使用接口.但具有讽刺意味的是,这意味着另一层(尽管很薄且易于管理).
还有什么?

我不习惯这种快速和松散的编程风格,所以也许我错过了一些明显的技巧.还有什么我应该考虑的吗?我相信我很快就会遇到其他问题.

编辑: 这个问题与DDD无关.并且注意到很多人都在使用传统的DDD方法--Saymann似乎得出了相同的结论,Rahien谈到了"抽象反模式的无用抽象",而Evans自己说DDD只在5%的情况下真正有用.案例.另见这个帖子.一些评论/答案可以预见我将如何做DDD错误,或者我如何调整我的系统来做正确的事.但是,我并不是要问DDD还是在适合的情况下抨击它,而是我想知道其他人在做什么符合我上面所描述的思路.这并不是说DDD是所有设计弊病的灵丹妙药,每十年都有一个新的流程出现(RUP任何人?XP,Agile,Booch,等等......).DDD是最新的,也是最知名和最常用的.但实用主义应该是第一位的,因为我正在努力建造能够按时发货且易于维护的可销售产品.到目前为止,我学到的最有用的编程公理是YAGNI.我想要的是将我的系统改为某种"DDD-lite",在这里我得到了强大的设计/ OOP /模式哲学,但没有脂肪.

eul*_*rfx 5

DDD的典型持久性方法是将域模型直接映射到相应的表.从技术上讲,映射仍然存在(并且通常在代码中声明),但是没有明确的数据模型,正如lazyberezovsky所指出的那样.

无论您是否使用DDD,导航属性的问题都可以通过几种不同的方式解决.我不喜欢方法1,因为它使你的代码更难以推理 - 你永远不知道将设置哪些属性,哪些不会.方法2在理论上要好得多,因为它使得非常明确的是给定查询需要什么,并且使事物明确是一般的好习惯.类似但更简单且不易损坏的方法是使用读取模型,读取模型只是旨在满足给定查询集查询要求的对象.在DDD的上下文中,它们允许您将行为丰富的实体与查询分离,这些查询通常存在争议.现在,DRY的支持者可能会尖叫异端并用火把和干草叉向你走来,但实际上,维护读模型和实体通常要容易通过接口或复杂的映射来强制实体来满足查询要求策略.此外,阅读模型和行为模型的职责完全不同,因此DRY不适用.

这并不是说DDD适用于您的场景.避免完全成熟的DDD通常是一个明智的决定,特别是在主要是CRUD的情况下.谨慎是正确的,这是KISS和YAGNI的一个很好的例子.当您的域包含复杂行为而不仅仅是数据时,DDD会获益.无论如何,读取模型模式适用.

UPDATE

对于不使用读取模型的实现,请查看获取策略设计,其中获取策略的概念允许从数据库中精确地指定所需的内容,从而减轻导航属性的问题.链接帖子中引用的材料也很有用.总的来说,这试图避免其他方法中存在的一层间接.但是,在我看来,使用提议的提取策略比使用读取模型更复杂,而最终结果是相同的.