Шаблон спецификации против метода расширения? - PullRequest
6 голосов
/ 01 апреля 2011

Я пытаюсь понять образец спецификации, и я немного запутался по этому поводу.Я действительно не мог найти это полезным для моих конкретных требований.Я хочу знать, в чем проблема, если я предпочитаю методы расширения для своих сложных спецификаций?Например,

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

Мне показалось полезным обернуть мои длинные спецификации с помощью методов расширения вместо использования шаблона спесификации.Что не так с этим?

Ответы [ 3 ]

5 голосов
/ 01 апреля 2011

Нет ничего плохого в вашем текущем подходе.

Шаблон спецификации как очень общая концепция имеет смысл, когда вы имеете дело с комбинациями, которые могут быть произвольно применены, потому что они выражают ортогональные концепции - то есть продукт является микроволновой ион также весит менее 5 фунтов.

Методы расширения имеют смысл, когда вы хотите сгруппировать определенные условия, которые всегда появляются вместе, т.е. продукт есть на складе, и мы все еще предлагаем его для создания более простой в использовании абстракции, т. е. InStock.Другое использование методов расширения состоит в том, чтобы позволить более «плавную» композицию вашего окончательного запроса, которую многие предпочитают.

Обе концепции не являются взаимоисключающими, и вы должны использовать то, что приводит к самому читаемому коду для всех, кто выпытаясь выразить.

3 голосов
/ 01 апреля 2011

В то время как шаблон спецификации сфокусирован на построении списка критериев с помощью цепочки методов, а затем проверяет один объект по этому критерию, LINQ стремится сосредоточиться на создании запроса на преобразование с помощью цепочки методов. Преобразование может включать ссылки на критерии (Where), но возможны и другие ссылки.

Я не вижу оснований думать, что шаблон спецификации "лучше", чем шаблоны, установленные каркасом LINQ, поэтому ваш подход не обязательно "неправильный". Однако имейте в виду, что ваш метод будет работать только с IQueryable объектами, а не с IEnumerable объектами. Это может вызвать ограничения, когда речь идет об использовании таких технологий, как LINQ to Entities, которые не знают, как перевести .InStocks() в оператор SQL.

3 голосов
/ 01 апреля 2011

Шаблон спецификации позволяет программисту составлять данные во время выполнения. Это было бы более гибким, чем просто использование методов расширения. Например, что, если вы хотите IQueryable<Product> продуктов, которые есть в наличии И все продукты, которые либо были проданы на прошлой неделе, либо никогда не заказывались? Составление запроса, подобного этому, потребует от вас создания совершенно другого метода расширения, в котором шаблон спецификации позволит вам составить его с помощью простого API.

Интерфейс IQueryable фактически смягчает некоторые преимущества шаблона спецификации, но, на мой взгляд, разработчик не всегда понимает, как и где будут выполняться запросы с IQueryable, что может быть или не быть проблемой в зависимости от вашего обстоятельства.

...