7

维基百科指出,规范模式是可以通过使用布尔逻辑将业务逻辑链接在一起来重新组合业务逻辑的地方。关于从列表或集合中选择过滤对象,在我看来 Dynamic LINQ 允许我完成同样的事情。我错过了什么吗?规范模式是否还有其他需要考虑的好处?


编辑:

我发现了一些讨论结合 LINQ 和规范模式的帖子:

Linq 规范项目

Nicloas Blumhardt (Autofac dude) 通过 Linq 实现规范模式

有没有人走过这条路并且维护变得复杂?

4

4 回答 4

6

我是 C# 开发人员,喜欢使用规范模式,因为它更接近我的业务领域。此外,您不会对这种模式感到惊讶,如果存在规范类,它应该可以工作。使用 Linq,您的底层提供者可能还没有实现某些功能,直到运行时您才会知道。

但可以肯定的是,规范相对于 linq 的最大优势是更接近业务,它是一个迷你 DSL。LINQ 对我来说是一个用于集合查询的 DSL,而不是用于业务领域。

于 2009-09-21T11:35:04.513 回答
3

林克:

var oldMans = Persons.Where(x => x.Sex == SexEnum.Masculine && x.Age > 60).ToList();

规格:

var oldMans = Persons.Where(x => IsOldManSpecification(x)).ToList();
  • 业务逻辑被封装在规范中(用一个名称来揭示它是什么)。
  • DRY:您不会在代码上重复该 linq,您只需使用规范

当我认为规则足够重要以在代码中明确并且它不自然地属于实体时,我喜欢使用规范。

例子:

public class Customer
{
    //...

    public bool IsAbleToReceiveCredit(decimal creditValue)
    {
        var secureAge = this.Age > 18 && this.Age < 60;
        var personalAssetsGreaterThanCreditValue = this.PersonalAssets.Sum(x => x.Value) > creditValue;

        return secureAge && personalAssetsGreaterThanCreditValue;
    }
}

是否由Customer责任决定他是否能够获得一些功劳?银行会问客户是否可以收到贷款?

可能不是。

Customer因此,通过规范,您可以从(它从未属于它)中删除该逻辑。您可以创建类似的东西IsAbleToReceiveCreditSpecification并将所有逻辑放在那里。我们可以进一步结合规范,例如:您可以创建 aSecureAgeSpecification和 aAssetsGreaterThanSpecification并使用它们来组成IsAbleToReceiveCreditSpecification.

所以我认为 LINQ 不会取代规范。事实上,它改进了模式。有一些规范的实现在内部使用 LINQ IQueriable<T>,这样您就可以在存储库/数据访问级别的 ORM 查询中使用规范。

于 2016-01-06T16:10:56.657 回答
2

动态 LINQ 使用字符串表达式来允许动态查询构造。所以我们实际上确实失去了那里的类型安全性。而使用包装器模式,如它密切相关的化身的装饰器模式,规范模式,允许我们维护代码中的类型安全。我探索使用装饰器模式作为查询包装器,以便重用和动态构建查询。您可以在以下位置找到有关代码项目的文章: Linq Query Wrappers

或者你可以查看我的博客

于 2010-07-15T13:29:36.663 回答
1

我真的不了解 LINQ,但在我看来,声明式查询系统通常与规范模式有关。特别是,通过在面向对象的环境中组合对象来实现声明式查询系统。IIRC 类似于 LINQ 所做的,提供一层语法糖。

LINQ 是否完全淘汰了这种模式,我无法判断。也许有一些在 LINQ 中无法表达的极端情况?

于 2009-09-21T11:35:57.627 回答