【问题标题】:Specification Pattern defined in Domain域中定义的规范模式
【发布时间】:2009-09-17 17:00:23
【问题描述】:

使用 Linq to SQL 和具有解耦存储库的 DDD 样式域层,是否有人对如何实现 specification pattern 而不会将 L2S 问题渗透到域层有任何好的想法,这仍然可以理解吗? :)

我们有围绕一组交易数据选择的复杂业务逻辑,并希望这些规则/规范归域所有。我们在保持域持久性无知方面也做得很好。

这带来了一个问题,因为为了实现规范,域(据我所知)需要查看正在查询的类型(L2S 类型)。

有什么想法吗?

另外,由于我不想解释的原因,nHibernate 是不可能的.. :)

【问题讨论】:

标签: linq-to-sql domain-driven-design specification-pattern


【解决方案1】:

您是否考虑过将您的通用规范映射到Expression 树中,该树将转换为正确的 L2S 语法?这似乎是您在这里遇到的主要问题。规范模式不是问题,但映射到 L2S 是问题。

【讨论】:

    【解决方案2】:

    Linq-To-Sql 类可以是部分的。这意味着您可以通过实现实现通用接口的部分来扩展它们。该接口可以在层之间共享,而不会出现您描述的“出血”问题。剩下的只是你的“IsStatisfiedBy”的细节,应该很容易封装。

    【讨论】:

      【解决方案3】:

      我最近遇到了同样的问题。不同的模式,但仍然是 LINQ to SQL (L2S)。我尝试了两种不同的方法来避免泄漏。

      首先我们尝试使用 DTO 和映射层。所以我们编写了超级简单的对象,这些对象与表具有一对一的映射关系。它们都装饰有 L2S 属性。然后,我们编写了一个映射层来将 DTO 映射到我们的业务对象。所有这些都通过 Doman Driven Design 的存储库模式隐藏起来。所以业务对象的消费者不知道 L2S 是在底层。

      接下来,主要是为了多样化。我们尝试使用 L2S 的 XML 映射功能,因此对象本身不需要属性。对于集合,我们公开了 IEnumerable 而不是任何 L2S 集合。如果您查看业务类的内部结构,您仍然可以检测到 L2S(EntitySet 或 Ref)的一些用法。但是这个阶级的消费者不知道。所以有一些泄漏,但没什么大不了的。

      最后我们坚持第一个模式。第二个可行,我们可以在不更改业务层接口的情况下替换 L2S,但我对 XML 映射从来不满意。第一个模式在数据库和业务对象之间有一个更清晰的分离。它需要更多的代码。第一个对我们也更有效,因为它允许我们以不同于表的方式发展业务对象。在项目的早期,xml 映射很有效,因为我们的对象与表几乎是一对一的。

      所以最后我们在 L2S 和域之间放置了一层。有效。它需要更多的代码,但它真的很简单。这一切都非常可测试。

      【讨论】:

      • 我解决了 L2S 泄漏的问题,但现在的问题是如何让我的域对象拥有自己的规范(如在规范模式中),而不必从我的域层引用 L2S。
      • 我想我没有确切地看到你卡在哪里。我们使用我提到的第一种技术来保持我们的域和 L2S 相距甚远,并且我们正在使用规范模式。我们的规范作用于域对象,我们有 DDD 风格的服务来获取规范。多亏了映射层,如果这些规范需要来自数据库的参数,它都隐藏在映射层后面。
      【解决方案4】:

      如果您想避免从域层引用 Linq2Sql,则必须使用代表实体的接口,而不是使用实际实体本身。然后,您需要在接口和实体之间建立一个映射层。

      我一直以这种方式工作,发现它是一个严重的障碍。我为新项目切换到 NHibernate,而对于旧项目,我不再担心域直接引用 Linq2Sql 实体。在我看来,克服这个限制实在是太耗费时间了。

      【讨论】:

      • 我们目前将我们的域放在一个单独的程序集中,并且 L2S 隐藏在存储库实现之后。域程序集根本没有对数据上下文或任何 L2S 的引用。所以我们在那里取得了成功。我可能对规范模式的想法有误,但我试图将规范传递给存储库,但让域层拥有这些规范。 L2S 创建它自己的类型,所以为了编写规范,我必须引用这些类型,这会将这些问题泄露到我的领域。听起来 nHibernate 会解决这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 2013-08-13
      相关资源
      最近更新 更多