Шаблон проектирования для фильтрации коллекции элементов?

StackOverflow https://stackoverflow.com/questions/1622474

Вопрос

Представьте себе типичный тип приложения, в котором у вас есть список элементов с разными свойствами.Например.древовидное представление со 100 элементами, каждый из которых имеет имя, а рейтинг, а в рейтинге самых популярных товаров на планете и т. д.Вероятно, существуют также отношения «многие ко многим» между предметы и каталоги товаров, или между предметы и создатели предметов и т. д. и т. д.

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

Задача проектирования такой функции фильтрации должна быть чем-то, что сделали МНОГИЕ разработчики, и наверняка должен быть какой-то шаблон проектирования, который наиболее подходит для этой задачи.

Любой?

Редактировать: Переключился на вики сообщества, так как подозреваю, что для этого не используется какой-либо отраслевой шаблон.Вопрос, наверное, слишком обобщенно сформулирован.

Это было полезно?

Решение

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

  1. Базовая коллекция должна остаться неизменной после фильтрации.
  2. Результат не стойкий

Классический подход заключается в использовании Просмотры.Это в основном ленивое программирование, где вы создаете объект, который может получить доступ к исходной коллекции и знает, какой фильтр нужно применить, но не будет выполнять никаких вычислений, пока ничего не требуется.

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

Например:

Collection myCollection;
Predicate myFilter;

// Nothing is computed here
View<Predicate> myView(myCollection, myFilter);

// We iterate until we find the first item in the collection that satisfies
// the Predicate, and no more, to initialize `begin`
View<Predicate>::Iterator begin = myView.begin(), end = myView.end();

Чистое преимущество заключается в том, что если вам (скажем) нужны только 10 первых элементов, то вы будете применять предикат только столько, сколько необходимо, чтобы найти эти 10 первыми, и не более того.

Кроме того, не существует копии задействованных элементов, и ваше представление гарантированно будет обновлено, даже если вы измените myCollection, хотя это может повлиять на достоверность итераторов (как обычно).

Проблема в том, что (если вы не реализуете кеширование) результат вычисляется каждый раз.

Если вам нужен более устойчивый результат, лучше создать новую коллекцию, содержащую только отфильтрованные элементы (или ссылки на них).Здесь нет общего шаблона, поскольку это зависит от того, как вы хотите использовать «отфильтрованный» список.

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

Составной шаблон особенно подходит для представления результата анализируемого выражения. Например, вам может понадобиться взглянуть на деревья выражений, чтобы получить представление.

Другие советы

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

Например, в LINQ есть удобный способ сортировки с использованием деревьев выражений.

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

Если вы работали с чем-то вроде javascript, функцию сортировки можно было бы создать «на лету».

мне нравится фильтр с предикатом из Коллекции Google и я бы реализовал что-то очень похожее, если бы не мог это использовать.Вы можете проверить этот ответ на аналогичный вопрос для примера реализации.Реализация на Java, но вы увидите шаблон.

Вы ищете реляционную базу данных, из которой можно использовать SQL.Вы можете поставить полную базу данных и подключиться к ней из своего приложения, а можете сделать что-то среднее между полной базой данных и прямыми объектами.Например, в Java вы можете использовать базу данных в памяти, например HSQLDB/JavaDB, и использовать ее возможности.Вы также можете использовать ДжоSQL что позволит вам работать с SQL непосредственно над вашими объектами вообще без базы данных.

Альтернативно, если вы хотите запрограммировать это самостоятельно, вам следует начать с сохранения двух копий ваших данных.Один — это полный набор данных, другой — ваше представление о данных после фильтрации.Затем вы создадите индекс своих данных для каждого столбца, отсортировав данные и сохранив их положение в отсортированном списке.Та же настройка работает и для сопоставления фильтра.Если что-то соответствует фильтру для столбца, присвойте этому значение 1 или 0, если нет.Затем, когда кто-то меняет порядок сортировки, вы копируете свои данные из полного списка в список просмотра или при изменении информации фильтра вы берете только те данные, которые имеют совпадение.

Если эти отношения выражаются как RDF и OWL, вы можете использовать инструмент с конечной точкой SPARQL (например, Jena) или средство рассуждения, такое как Pellet.Но без более подробной информации не ясно, что это лучший подход.

Посмотрите, если http://en.wikipedia.org/wiki/Criteria_Pattern могу помочь тебе.Основано на шаблоне спецификации

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top