Шаблон проектирования для фильтрации коллекции элементов?
представьте себе типичный тип приложение, где у вас есть список элементов с различными свойствами. Е. Г. дерево-взгляд с 100 элементов, каждый из которых имеет имя, a рейтинг, a ранг-в-в-горячих-предметов-на-планета etc. Вероятно, между предметы и пункт-каталоги или предметы и пункт-создатели etc etc.
теперь это приложение, естественно, нуждается в системе фильтрации. Е. Г. где я могу строить сложные фильтры с несколькими условиями всех видов, между данными в разных отношениях.
задача проектирования написания такой функции фильтрации должна быть чем-то, что сделали многие разработчики, и наверняка должен быть какой-то шаблон дизайна, который наиболее подходит для этой задачи.
кого?
Edit: переключился на сообщество wiki, так как я подозреваю для этого не используется никакой отраслевой шаблон de factor. Вопрос слишком обобщенно сформулирован.
6 ответов
на самом деле немного сложно указать, чего вы хотите, поэтому я возьму свои собственные предположения.
- базовая коллекция должна быть неизменной после фильтрации
- результат не является постоянным
классическим подходом является использование вид. Это в основном ленивый программирования, где вы создаете объект, который может получить доступ к исходной коллекции и знает фильтр для применения, но не сделает расчет пока ничего не требуется.
в коллекциях представления часто реализуются с помощью итераторы, и для фильтрации, конечно, шаблон стратегии, как уже указывалось.
например:
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, то функция сортировки может быть создана на лету.
Мне нравится фильтр с предикатом of Google Коллекции и я бы реализовал что-то очень похожее, если бы не мог его использовать. Вы можете проверить ответ к аналогичному вопросу для примера реализации. Реализация в Java, но, ну, вы увидите узор.
вы ищете реляционную базу данных, из которой вы можете использовать SQL. Вы можете встать полный и подключиться к нему из приложения, или вы можете сделать что-то между полной базе и прямые объекты. Например, в Java вы можете использовать базу данных в памяти, такую как HSQLDB / JavaDB, и использовать ее функции. Вы также можете использовать JoSQL что позволит вам работать в SQL непосредственно на ваших объектах без базы данных вообще.
кроме того, если вы хотели запрограммировать вещь самостоятельно, вы бы начать, сохраняя 2 копии ваших данных. Один-это ваш полный набор данных, другой-ваше представление данных после фильтрации. Затем вы создадите индекс для своих данных для каждого столбца, сортируя данные и сохраняя их позицию в отсортированном списке. Такая же настройка работает для соответствия фильтра. Если что-то соответствует фильтру для столбца, дайте ему 1 или 0, если нет. Затем, когда кто-то переключает порядок сортировки скопировать данные из полного списка в список представлений или при изменении информации о фильтре вы будете брать только те данные, которые совпадают.
Если эти отношения выразимы как RDF и OWL, вы можете использовать инструмент с конечной точкой SPARQL (например, Jena) или аргументом, таким как Pellet. Но без более подробной информации не ясно, что это лучший подход.
ли http://en.wikipedia.org/wiki/Criteria_Pattern могу помочь вам. Основан на спецификации pattern