2

我有一个需要通过不同类型的过滤器处理的活动列表,例如平台过滤器、应用程序过滤器、CampaignRunning 过滤器,以检查当前日期是否应该在开始日期和结束日期之间等。

理想情况下有 15-20 种不同的过滤器,我使用Intercept Design Pattern管理它们。

在应用过滤器之前列表可能为空,所以我应该NullValueFilter在过滤器链中使用吗?

再次应用一些过滤器列表后可以为空,以检查我是否应该使用策略设计模式注入相同的空或空检查策略?

我通常会更多地考虑设计视角来管理此类案例。我想知道我是否在思考正确的方向,或者我是否在这方面过度设计。

一些伪代码来说明场景 -

Class NullValueFilter : IFilter {
  Execute(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
    }
    return true;
  }
}

Class PlatformFilter : IFilter {
  Execute(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
    }
    campaignList = campaignList.Where( x => x.Platform == 'Mobile');
    return true
  }
}

Class CampaignRunningFilter : IFilter {
  Execute(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
    }
    // first Fetch campaign start date and end date 
    
    campaignList = campaignList.Where( x => x.startdate <= curr_date && x.enddate >= curr_date);
    return true
  }
}

我可以在这里想到两个选择 -

  1. 创建一个过滤器基类,可以管理列表的空和空检查。
  2. 使用构造函数注入在每个过滤器中注入空值过滤器实例,并调用该空值和空值检查方法。
4

2 回答 2

2

对于 15 到 20 个过滤器,我根本不会对空列表进行任何检查,这会使事情变得比必要的更复杂而没有任何明显的好处。

每个过滤器在传递一个空列表时都表现得完全一致,所以我看不出有任何令人信服的理由说明这种“断链”的过早优化是必要的。最干净的设计是恕我直言,我们已经将任何不必要的废物扔到了船上,所以这就是我要开始的。

但是,如果您通过在空列表处停止处理确实注意到可测量的相关性能改进,我不会让过滤器测试这种情况。相反,让调用者直接测试它,而不是检查布尔返回码。我建议让该Execute方法返回过滤后的列表,并按照以下代码段的方式实现它:

 List<Campaign> campaignList = ...;  // init this here
 foreach(IFilter filter in GetActiveFilters)
 {
      if(campaignList==null || campaignList.Count == 0)
          break;
      campaignList = filter.Execute(campaignList);
 }

这样,代码中只有一个地方需要实现空列表测试,您不必在过滤器中一遍又一遍地重复这一点。

于 2021-10-06T12:56:15.687 回答
1

我们是否可以创建一个抽象类来公开一个公共方法 Execute,该方法将负责调用另一个受保护的抽象方法让我们说 ExecuteFilter 并有条件地调用它,所有过滤器都将实现这个抽象类,例如:

Class AbstractBaseFilterClass : IFilter {
    public Execute(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
       }
      ExecuteFilter(campaignList);
   }
   protected abstract boolean ExecuteFilter(List<CampaignList> campaignList);
}


Class PlatformFilter : AbstractBaseFilterClass {
  ExecuteFilter(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
    }
    campaignList = campaignList.Where( x => x.Platform == 'Mobile');
    return true
  }
}

Class CampaignRunningFilter : AbstractBaseFilterClass {
  ExecuteFilter(List<CampaignList> campaignList) {
    if(campaignList != null && campaignList.Count == 0) {
         return false;
    }
    // first Fetch campaign start date and end date 
    
    campaignList = campaignList.Where( x => x.startdate <= curr_date && x.enddate >= curr_date);
    return true
  }
}

// client can call it simply
 List<Campaign> campaigns = ...;
 foreach(IFilter filter in Filters)
 {
     filter.Execute(campaignList);
 }

于 2021-10-06T14:39:13.590 回答