规格模式与扩展方法?

时间:2011-03-31 20:09:54

标签: c# .net specification-pattern

我正在努力掌握规范模式,我对此感到困惑。我真的觉得它对我的具体要求没有帮助。我想知道如果我更喜欢扩展方法来解决我的复杂问题,那会是什么问题?例如

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

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

3 个答案:

答案 0 :(得分:5)

您当前的方法没有任何问题。

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

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

这两个概念并不相互排斥,你应该使用最可读代码的结果来表达你想要表达的内容。

答案 1 :(得分:3)

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

IQueryable接口实际上减轻了规范模式的一些优点,但在我看来,开发人员并不总是清楚地知道如何以及在哪里使用IQueryable执行查询,这可能是也可能不是问题,具体取决于你的情况。

答案 2 :(得分:3)

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

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