我们应该在拦截设计模式实现中使用 NullValueFilter 吗?

Posted

技术标签:

【中文标题】我们应该在拦截设计模式实现中使用 NullValueFilter 吗?【英文标题】:Should We use NullValueFilter in Intercept Design Pattern Implementation? 【发布时间】:2021-11-25 16:02:49 【问题描述】:

我有一个需要通过不同类型过滤器处理的广告系列列表,例如平台过滤器、应用程序过滤器、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
  


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

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

【问题讨论】:

@DocBrown 伪代码添加供您参考。 好的,我看到你的“空值过滤器”没有过滤任何东西,它只是检查空列表,返回真或假。但是这将如何影响过滤呢? ...和第二个问题:为什么所有这些检查都需要空列表?在我看来,如果没有检查,所有这些过滤器都可以正常工作:空列表输入给出空列表。 首先,Null Value Filter 将只检查 null 并决定是否应该执行下一个过滤器或中断链。其次,我只想避免在空列表上执行下一个过滤器链。 【参考方案1】:

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

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

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

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

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

【讨论】:

【参考方案2】:

我们可以创建一个抽象类来公开一个公共方法 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);
 

【讨论】:

以上是关于我们应该在拦截设计模式实现中使用 NullValueFilter 吗?的主要内容,如果未能解决你的问题,请参考以下文章

#私藏项目实操分享# Mybatis自定义拦截器与插件开发

Java Web学习Java拦截器

13.代理模式

SpringBank 开发日志 一种简单的拦截器设计实现

mybatis拦截器

mybatis 实现 SQL 查询拦截修改详解