代码之家  ›  专栏  ›  技术社区  ›  David Robbins

当您可以使用动态LINQ时,规范模式是否已过时?

  •  7
  • David Robbins  · 技术社区  · 16 年前

    Wikipedia 声明规范模式是通过使用布尔逻辑将业务逻辑链接在一起来重新组合业务逻辑的地方。关于从列表或集合中选择筛选对象,我认为动态LINQ允许我完成相同的事情。我错过什么了吗?规范模式还有其他应该考虑的好处吗?


    编辑:

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

    Linq Specifications Project

    Implementing the Specification Pattern via Linq by Nicloas Blumhardt (Autofac dude)

    有没有人走这条路,维修起来很复杂?

    4 回复  |  直到 8 年前
        1
  •  2
  •   Aki la Anirudha    9 年前

    动态LINQ使用字符串表达式来允许动态查询构造。所以我们确实在那里失去了类型安全。而使用包装模式(如与之密切相关的decorator模式)规范模式,则允许我们在代码中维护类型安全。为了重用和动态构建查询,我研究了使用decorator模式作为查询包装器。有关代码项目的文章,请访问: Linq Query Wrappers

    或者你可以查一下我的 blog .

        2
  •  5
  •   Nicolas Dorier    16 年前

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

    但明确地说,规范相对于LINQ的最大优势是更接近业务,它是一个小型DSL。对于我来说,Linq是用于集合查询的DSL,而不是用于业务域。

        3
  •  1
  •   Wouter Lievens    16 年前

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

    我不知道Linq是否完全废弃了这个模式。也许有些角落的情况不能用LINQ表示?

        4
  •  1
  •   fabriciorissetto    8 年前

    LINQ:

    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 这个 响应能力 决定他是否能获得一些荣誉?银行会问顾客是否能得到贷款?

    大概不会。

    因此,通过规范,您可以从 顾客 (它从不属于它)。你可以创造出 IsAbleToReceiveCreditSpecification 把所有的逻辑放在那里。我们可以进一步组合规范,例如:您可以创建一个 SecureAgeSpecification 还有一个 AssetsGreaterThanSpecification 用它们组成 IsableToReceiveCreditSpecification(IsableToReceiveCreditSpecification) .

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