Мы можем оптимизировать паттерн Pipeline & Filter (конвейер и фильтры), сократив количество кода, необходимое на его реализацию, используя лямбда-выражение (упрощенную запись анонимных методов) в качестве конкретного условия фильтрации. В качестве примера для демонстрации этой концепции, было выбрано WPF-приложение с пользовательским интерфейсом. Вот его исходный код.
Обычно в рамках этого паттерна для каждого нового фильтра реализуется интерфейс. Вместо того чтобы реализовывать интерфейс для каждого условия фильтрации, в качестве входных данных для конвейера фильтров можно использовать обобщенное (generic) лямбда-выражение. В результате кода станет меньше. Ниже представлена диаграмма классов:
ConditionAggregator
– это конвейерный класс, в котором хранится коллекция Condition<T>
. Filter<T>
владеет ConditionAggregator
или Condition<T>
для применения условий (condition) фильтрации к набору данных. Когда вызывается функция apply (применить) Filter<T>
, выполняется метод check (проверить) ICondition<T>
. ConditionAggregator<T>
имеет событие OnFilterChanged
. Оно срабатывает, когда в классах модели представления изменяется значение коллекции или условия. В следующем разделе будет описано использование паттерна Filter моделью представления.
Использование в модели представления
Объяснение паттерна MVVM можно найти по этой ссылке. Одна из обязанностей модели представления (View Model) в MVVM – обрабатывать взаимодействие с пользователем и изменения данных. В нашем случае изменения значений условий фильтрации должны быть переданы на бизнес-уровень, чтобы применить фильтры к определенной коллекции данных. Изменение значения условия в модели представления стригерит событие ConditionAggregator<T>
OnFilterChanged
, на которое подписан метод фильтра apply. Ниже приведена диаграмма классов модели представления.
Класс сущности Employee
создан для хранения информации о сотрудниках. Generic
тип T
паттерна проектирования Filter
будет заменен классом Employee
. EmployeeList
содержит список данных о сотрудниках и применяемые фильтры. Конструктор класса получает список условий и переходит к списку фильтров.
public EmployeeList(IEmployeesRepository repository, ConditionAggregator<employee> conditionAggregator)
{
this.repository = repository;
this.filters = new ConcreteFilter<employee>(conditionAggregator);
conditionAggregator.OnFilterChanged += this.FilterList;
_ = initAsync();
}
Метод FilterList
подписан на событие OnFilterChanged
для применения фильтров к данным, когда происходит изменение условия или значения.
private void FilterList()
{
this.Employees = this.filters.Apply(this.employeesFullList);
}
EmployeesViewModel
подключен к пользовательскому интерфейсу. В этом примере продемонстрирован только один фильтр свойства EmployeeTypeselected
, но в ConditionAggregator
можно передать множество фильтров. Следующий фрагмент кода – это метод-конструктор, в котором регистрируется условие фильтра.
public EmployeesViewModel(IEmployeesRepository repository)
{
this.repository = repository;
Condition<employee> filterEmployee = new Condition<employee>((e) => e.employeeCode == this.EmployeeTypeSelected);
this.conditionAggregator = new ConditionAggregator<employee>(new List<condition<employee>> { filterEmployee });
this.EmployeeList = new EmployeeList(repository, this.conditionAggregator);
}
</condition<employee></employee></employee></employee>
Условие передается как лямбда-выражение. Их может быть сколько угодно, поскольку конструктор ConditionAggregator
принимает список условий фильтрации. Основная цель уменьшить код, необходимый для создания определенного класса условий фильтрации, достигнута.
WPF.Demo.DataFilter
– это представление пользовательского интерфейса WPF. Он имеет одну сетку и одно поле со списком для фильтрации. Проект WPF.Demo.DataFilter.ViewModels
обрабатывает данные, фильтрует изменения и перезагружает данные для обновления пользовательского интерфейса. Проект WPF.Demo.DataFilter.Common
представляет собой полную реализацию шаблона Pipeline & Filter. WPF.Demo.DataFilter.DAL
загружает простенький json-файл в качестве хранилища данных.
Это основной интерфейс:
Перевод статьи был подготовлен в преддверии старта курса “Архитектура и шаблоны проектирования”. А прямо сейчас приглашаем всех желающих на бесплатный демо урок в рамках которого обсудим назначение и структуру шаблона “Интерпретатор”, формы Бекуса-Науэра, лексический, синтаксический и семантический анализы, а также разберем практические примеры. Записаться на урок можно по ссылке.
VK объявляет о приобретении 40% компании Intickets.ru (Интикетс). Это облачный сервис для контроля и управления продажей билетов на мероприятия. Сумма…
OpenAI готовится запустить собственную поисковую систему на базе ChatGPT. Информацию об этом публикуют западные издания. Ожидается, что новый поисковик может…
Центр управления связью общего пользования (ЦМУ ССОП) Роскомнадзора рекомендовал компаниям из реестра провайдеров ограничить доступ поисковых ботов к информации на российских сайтах.…
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…