使用规范模式

时间:2010-03-24 09:15:22

标签: c# specification-pattern

与任何设计模式一样,Specification Pattern是一个很好的概念,但很容易被热切的架构师/开发人员过度使用。

我即将开始开发一个新的应用程序(.NET& C#),并且非常喜欢规范模式的概念,我很想充分利用它。然而,在我开始使用所有枪支之前,我真的很想知道是否有人可以分享在开发应用程序时使用Specification Pattern时遇到的痛点。

理想情况下,我想看看其他人是否有问题

  • 根据规范模式编写单元测试
  • 决定规范应该存在哪个层(存储库,服务,域等)
  • 当一个简单的if语句完成这项工作时,无处不在地使用它
  • 等?

提前致谢

3 个答案:

答案 0 :(得分:14)

我不相信LINQ是规范模式的替代品。请记住,规范最适合用于封装业务逻辑。因此,如果我的业务要求之一让我获得了几个功能的所有重要客户,我的Linq声明可能如下所示:

var valuedCustomers = Customers.Where(c => c.Orders.Count > 15 && c.Active).ToList();

我可以在我的应用程序中输入此声明,但如果我想在某个日期之前附加客户必须加入的规则,该怎么办?好吧,现在我必须遍布我的应用程序并更改Linq。或者如果我的对象图改变了(尽管这不应该是使用该模式的唯一原因)。相反,我可以做这样的事情

var valuedCustomers = Customers.Where(new ValuedCustomerRule.IsSatisfied()).ToList();

我同意该模式已被过度使用,但它对于整个系统中出现的业务规则非常有用,因此当这些规则发生变化时您不会被咬。对我而言,它类似于在整个应用程序代码中保留SQL查询。

答案 1 :(得分:9)

正如大卫在他的评论中指出的那样,现在可以通过LINQ等更简洁地实现许多有关规范的用处。

您可以即时创建任意规范,而不是新的规范类型: GetCustomers().Where(customer => customer.IsActive && customer.City == "Oakland");

然而,由于以下几个原因,这并不完全取代规范:

  1. 在返回所有客户后,在消费类中进行排序/过滤。如果您正在处理内存中对象以外的任何内容,则这是次优的(LINQ-to-SQL等是例外,因为它们编译和优化查询并在服务器/远程端执行它们,只返回所需的结果)。
  2. 如果您公开集合并将规范留给LINQ查询,那么您的API对任何查询都是开放的。如果您想限制检索的内容或数量,您需要一组规范来查询。
  3. 当然没有必要在任何地方使用它,你很可能根本不需要它;我不知道你的域名或你在做什么。

    我认为最好的建议不是来使用它。您将看到何时有必要,最有可能的时候您开始编写的类看起来就像您链接的文章中的第一个示例。

    只需将它保存在您的心理模式存储库中,这样您就可以得到它;如果你从不使用它,那只意味着你不需要它,那很好。

    层的选择取决于规格和用途的性质。在许多情况下,它们是支持服务层的助手,但在某些情况下,它们封装了域逻辑。

    对于单元测试,请记住您的规格是单位或包含单位。不要测试接受具有所有可能的规范组合的规范的方法;测试规范本身以确保它们的行为符合预期,然后您可以在许多方法和类中放心地重用相同的规范。

    希望这有点帮助。

答案 2 :(得分:1)

更新的答案: 我同意Wix,LINQ不是规范模式的替代品。我没有足够的声誉来为Wix答案添加评论,我只是回复作为答案。

根据this paper规范主要用于将域对象与语句匹配。虽然规范在与域对象匹配时返回true / false,但这确实意味着规范 建议在代码中封装任何布尔条件。

我将继续进行Wix的回答。如果您已定义ValuedCustomer规范,则您具有使用规则的不同可能性:

import Data.List
import Data.List.Split

replace needle replacement haystack =
    intercalate replacement (splitOn needle haystack)

rep = foldl' replace' ['A'..'Z'] . splitOn "."
    where
        replace' az [a,b] = replace [a] [b] az

我对paper的理解是,用户可以与规范进行交互以实现其目标,前提是需要它并且您的应用UI允许它。

上面提到的论文还提到了何时不使用规范模式。