过滤列表违反开闭原则

Filtering list violates open–closed principle

我写了一个通过参数过滤列表的方法,效果很好。但我担心违反“开闭原则

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

目前,如果我想再添加一个过滤器,我需要 修改 Params class 和 过滤器 方法。

我想问 如何重构这些实体以使其可扩展? 或者这可能是个愚蠢的问题,我不需要在这里重构任何东西?如果有任何想法,我将不胜感激。

过滤方式:

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;
}

参数class:

 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; }
    }

如果您希望过滤逻辑可扩展,您可以为过滤条件创建一个基础 class:

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

对于每个条件,您将创建一个派生自 FilterCriteria 的 class,例如:

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 派生一个新的 class;您不必再更改 Params 和全局 Filter 方法。