6

我正在尝试掌握规范模式,但我对此感到有些困惑。我真的找不到它对我的特定要求有帮助。我想知道如果我更喜欢复杂规范的扩展方法有什么问题?例如

public static class ProductExtensions
{
    public static IQueryable<Product> InStocks(this IQueryable<Product> query)
    {
        return query.Where(p => p.InStock && !p.IsDeleted /*others goes here*/);
    }
}

我发现用扩展方法而不是使用规范模式来包装我的长规范很有帮助。这有什么问题?

4

3 回答 3

5

你目前的做法没有任何问题。

当您处理可以任意应用的组合时,规格模式作为一个非常通用的概念是有意义的,因为它们表达了正交概念 - 即产品是微波炉,重量也小于 5 磅。

当您想要将总是一起出现的某些条件分组时,扩展方法是有意义的,即产品有库存,我们仍然提供它以形成更易于使用的抽象,即InStock. 扩展方法的其他用途是允许最终查询的更“流畅”组合,这是许多人喜欢的。

这两个概念并不相互排斥,你应该使用最易读的代码来表达你想要表达的东西。

于 2011-03-31T20:26:02.817 回答
3

规范模式允许程序员在运行时组合数据。这将比仅使用扩展方法更灵活。例如,如果您想要IQueryable<Product>有库存的产品以及上周售罄或从未订购过的所有产品怎么办?编写这样的查询需要您创建一个完整的其他扩展方法,规范模式将允许您使用简单的 API 来编写它。

IQueryable 接口实际上减轻了规范模式的一些优点,但在我看来,开发人员并不总是清楚如何以及在何处使用 IQueryable 执行查询,这取决于您的情况可能会或可能不会成为问题。

于 2011-03-31T20:23:57.420 回答
3

规范模式侧重于通过方法链接构建标准列表,然后根据该标准检查单个对象,而 LINQ 倾向于专注于通过方法链接构建转换查询。转换可以包括标准 ( Where) 链接,但其他链接也是可能的。

我看不出有任何理由认为规范模式比 LINQ 框架建立的模式“更好”,因此您的方法不一定是“错误的”。但是,请记住,您的方法仅适用于IQueryable对象,而不适用于IEnumerable对象。在使用 LINQ to Entities 等技术时,这可能会导致限制,这些技术不知道如何转换.InStocks()为 SQL 语句。

于 2011-03-31T20:25:30.460 回答