Список фильтрации нарушает принцип открытого-закрытого

Я написал метод, который фильтрует список по параметрам, он работает довольно хорошо. Но меня беспокоит нарушение "открытый-закрытый принцип".

Open–closed principle states that "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"

В настоящее время, если я хочу добавить еще один фильтр, мне нужен класс модифицироватьПараметры и метод Фильтр.

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

Метод фильтрации:

public IEnumerable<Meeting> Filter(Params params)
{
    IEnumerable<Meeting> selectedMeetings =  new List<Meeting>(_dataContext.Meetings);

    if (request.Description is not null)
        selectedMeetings = selectedMeetings.GetByDescription(request.Description);

    if (request.Name is not null)
        selectedMeetings = selectedMeetings.GetByResponsiblePerson(request.Name);

    if (request.Category is not null)
        selectedMeetings = selectedMeetings.GetByCategory(request.Category);

    if (request.Type is not null)
        selectedMeetings = selectedMeetings.GetByType(request.Type);

    if (request.StartDate is not null)
        selectedMeetings = selectedMeetings.GetByStartDate(request.StartDate);

    if (request.EndDate is not null)
        selectedMeetings = selectedMeetings.GetByEndDate(request.EndDate);
           
    if (request.AttendeeCount is not null)
        selectedMeetings = selectedMeetings.GetByAttendeesCount(request.AttendeeCount);

    return selectedMeetings;
}

Класс параметров:

 public class Params
    {
        public string? Description { get; set; }
        public string? Name { get; set; }
        public string? Category { get; set; }
        public string? Type { get; set; }
        public string? StartDate { get; set; }
        public string? EndDate { get; set; }
        public string? AttendeeCount { get; set; }
    }

Я думаю, что есть фундаментальное непонимание этого принципа. Open-Close, например, со списком, означает, что «вы разрешаете другому коду изменять данные в списке (добавлять, удалять, изменять порядок, редактировать элемент), но не изменять внутреннюю работу списка (как он сохраняется в памяти, и т.д).

gunr2171 16.05.2022 19:56

Я бы беспокоился о повторном присвоении input или использовании IEnumerables, а не о повторном вычислении списков с каждым вызовом метода, прежде чем проверять, соблюдается ли какой-то принцип модного слова.

gunr2171 16.05.2022 19:57

@gunr2171 спасибо! удалить input задания и изменить с List на IEnumerable.

Yoro 16.05.2022 21:34
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
3
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы хотите, чтобы логика фильтрации была расширяемой, вы можете создать базовый класс для критериев фильтрации:

public abstract class FilterCriteria 
{
  IEnumerable<Meetings> Filter(IEnumerable<Meetings> meetings, string input);
}

Для каждого критерия вы должны создать класс, производный от FilterCriteria, например:

public class DescriptionFilterCriteria : FilterCriteria
{
  public override IEnumerable<Meetings> Filter(IEnumerable<Meetings> meetings, string input)
  {
    return meetings.GetByDescription(input);
  }
}

Ваш метод Filter получит список фильтров вместо экземпляра Params и зациклится на нем:

public List<Meetings> Filter(IEnumerable<FilterCriteria> criteria)
{
    IEnumerable<Meetings> selectedMeetings = new List<Meetings>(_dataContext.Meetings);

    foreach (var crit in criteria)
      selectedMeetings = crit.Filter(selectedMeetings, input);

    return selectedMeetings;
}

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

Спасибо за отличный ответ! Это то, что я хотел. Единственное, что я хотел бы здесь изменить, это FilterCriteria абстрактный класс вместо Filter параметра метода string input добавить в свойство класса public string Input { get; set; }.

Yoro 16.05.2022 21:48

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