使用规范模式

Kan*_*ane 2 c# specification-pattern

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

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

理想情况下,我正在寻找其他人是否有问题

  • 编写单元测试规范模式
  • 确定规范应该存在哪个层(存储库,服务,域等)
  • 当一个简单的if陈述完成这项工作时,到处使用它
  • 等等?

提前致谢

Wix*_*Wix 15

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

var valuedCustomers = Customers.Where(c => c.Orders.Count > 15 && c.Active).ToList();
Run Code Online (Sandbox Code Playgroud)

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

var valuedCustomers = Customers.Where(new ValuedCustomerRule.IsSatisfied()).ToList();
Run Code Online (Sandbox Code Playgroud)

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


Jay*_*Jay 8

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

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

但是,由于以下几个原因,这不是规范的完全替代:

  1. 返回所有客户后,在消费类中进行排序/过滤.如果您正在处理内存中对象以外的任何内容,则这是次优的(LINQ-to-SQL等是例外,因为它们编译和优化查询并在服务器/远程端执行它们,只返回所需的结果).
  2. 如果您公开集合并将规范留给LINQ查询,那么您的API对任何查询都是开放的.如果要限制可以检索的内容或数量,则需要一组要查询的规范.

当然没有必要在任何地方使用它,你很可能根本不需要它; 我不知道你的域名或你在做什么.

我认为最好的建议是不要使用它.您将看到何时有必要,很可能当您开始编写类似于您链接的文章中的第一个示例的类时.

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

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

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

希望这有点帮助.