当您可以使用动态 LINQ 时,规范模式是否已过时?
Wikipedia 指出规范模式是可以通过使用布尔值将业务逻辑链接在一起来重新组合业务逻辑的地方逻辑。关于从列表或集合中选择过滤对象,在我看来,动态 LINQ 允许我完成同样的事情。我错过了什么吗?规范模式是否还有其他值得考虑的好处?
编辑:
我发现了一些讨论结合 LINQ 和规范模式的帖子:
通过 Linq 实现规范模式,作者:Nicloas Blumhardt(Autofac 兄弟) )
有没有人走过这条路,维护起来是否变得复杂?
Wikipedia states that the Specification Pattern is where business logic can be recombined by chaining the business logic together using boolean logic. With respect to selecting filtering objects from lists or collections it seems to me that Dynamic LINQ allows me to accomplish the same thing. Am I missing something? Are there other benefits to the Specification Pattern that should be considered as well?
Edit:
I've found some posts that discuss combining LINQ and the Specification Pattern:
Implementing the Specification Pattern via Linq by Nicloas Blumhardt (Autofac dude)
Has anyone gone done this road and did it become complicated to maintain?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我是一名 C# 开发人员,喜欢使用规范模式,因为它更接近我的业务领域。此外,您对这种模式不会有任何惊讶,如果存在规范类,它应该可以工作。使用 Linq,您的底层提供程序可能尚未实现某些功能,并且直到运行时您才会知道。
但肯定的是,规范相对于linq的最大优势是更贴近业务,它是一个迷你DSL。 LINQ对我来说是一个用于集合查询的DSL,而不是用于业务领域的。
I'm a C# developper and like to use the specification pattern, because it is closer of my business domain. Moreover, you don't have any surprise with this pattern, if a specification class exists, it should work. With Linq, your underlying provider maybe hasn't implemented some features, and you won't know it until runtime.
But definitively, the biggest advantage of specification over linq is to be closer to the business, it's a mini DSL. LINQ for me is a DSL for collection query, not for the business domain.
LINQ:
规范:
当我认为规则足够重要,需要在代码中明确显示并且它自然不属于实体时,我喜欢使用规范。
示例:
客户
是否有责任来决定他是否能够获得一些信用?银行会询问客户是否可以获得贷款?可能不会。
因此,通过规范,您可以从
Customer
中删除该逻辑(它从未属于它)。您可以创建类似IsAbleToReceiveCreditSpecification
的内容,并将所有逻辑放在那里。我们可以进一步组合规范,例如:您可以创建一个SecureAgeSpecification
和一个AssetsGreaterThanSpecification
并使用它们来组成IsAbleToReceiveCreditSpecification
。所以我不认为 LINQ 会取代规范。事实上,它改进了模式。有一些规范的实现在内部使用 LINQ 和
IQueriable
,这样您就可以在 Repository/DataAcess 级别的 ORM 查询中使用该规范。LINQ:
Specification:
I like to use specification when I think that the rule is important enough to be explicit in the code and it doesn't belongs naturally to the entity.
Example:
Is it from the
Customer
the responsability to decide if he is able to receive some credit? A bank would ask to the customer if he can receive a loan?Probably not.
So with specification you can remove that logic from the
Customer
(it never belonged to it). You can create something likeIsAbleToReceiveCreditSpecification
and put all logic there. We can go further and combine specifications, for example: you could create aSecureAgeSpecification
and aAssetsGreaterThanSpecification
and use them to compose theIsAbleToReceiveCreditSpecification
.So I don't think LINQ replaces the Specification. In fact it improves the pattern. There are some implementations of Specification that use LINQ internally with
IQueriable<T>
, with this you can use the specification inside your ORM queries on the Repository/DataAcess level.动态 LINQ 使用字符串表达式来允许动态查询构造。所以我们实际上失去了类型安全。而使用包装器模式(如与其密切相关的化身规范模式)的装饰器模式,可以让我们维护代码中的类型安全。我探索使用装饰器模式作为查询包装器,以便重用和动态构建查询。您可以在以下位置找到有关代码项目的文章:
Linq 查询包装器
或者您可以查看我的博客。
Dynamic LINQ uses string expressions to allow the dynamic query construction. So we do in fact lose the type safety there. Whereas using wrapper patterns like the decorator pattern of it closely related incarnation, the specification pattern, allows us to maintain the type safety in code. I explore using the Decorator Pattern as query wrapper in order to reuse and dynamically build queries. You can find the article on code project at:
Linq Query Wrappers
Or you can check my blog.
我并不真正了解 LINQ,但在我看来,声明性查询系统通常与规范模式相关。特别是,通过在面向对象的环境中将对象组合在一起来实现声明性查询系统。 IIRC 与 LINQ 的作用类似,提供了一层语法糖。
我无法判断 LINQ 是否完全废弃了该模式。也许有些特殊情况无法在 LINQ 中表达?
I don't know LINQ really, but it seems to me that a declarative query system in general is related to the specification pattern. In particular, implementing a declarative query system by composing objects together in an object-oriented environment. IIRC that's akin to what LINQ does, providing a layer of syntactic sugar.
Whether LINQ completely obsoletes the pattern, I can't tell. Maybe there are corner cases that just can't be expressed in LINQ?