zoukankan      html  css  js  c++  java
  • 通用可扩展过滤器的开发(背景 过程 收获)付源码

    Demo源码

    背景

      过滤指的是从原始数据集合筛选符合需求数据子集的一个过程。

      实际生产中的过滤需求总结下来一般有以下几个方面:

    1. 数据的类型不定,可能是一个字符串列表,也有可能是一个业务对象列表
    2. 有一系列的条件来判定数据是否有效,并且这些条件变化的相对频繁
    3. 需要获取满足某些特性的数据,比如1000个字符串列表中有100个是有效的数据(满足整形数据过滤),而需求是要在这100个有效数据中再筛选出满足[长度超过3]特性的作为最终的结果
    4. 对满足某种特性的结果的个数有要求,按上面的例子,可能满足长度超过3特性的至少要取4个,而满足包含1特性的取1个就可以了
    5. 对结果集的总数有要求,按上面的例子,虽然有100个数据都是有效的,但是我们只需要取到前20个就行,这样做一般也是为了性能考虑

      本文的目的在于构建一个通用的过滤框架,这个框架:

    1. 使用泛型,以应对处理不同的对象类型。
    2. 提供过滤器的注册接口,可以通过这个接口注册多个方法,只有对象通过所有这些方法的验证,该对象才能被称为有效数据
    3. 提供识别器的设置接口,识别器是一个方法,这个方法接收一个有效数据对象,然后判断出该对象所具有的特性(预先会根据业务定义好一个包含所有特性的枚举),最后返回特性对应的枚举
    4. 提供特性对应最小条数的设置接口,这个接口维护一个字典列表,字典的key是特性枚举,value是对应特性最少应获取的条数
    5. 提供结果集获取数设置接口。

    过程

      接下来,我们设计一个实例,来让大家了解一下如何使用,并起一个抛砖引玉的作用

      假设有一列字符串:"123","246","b","15","16","a32",我们需要在这组字符串中拿出一组子串,这个子串需要满足:

    • 若原始字符串列表中存在,取1个长度不小于3的整数
    • 若原始字符串列表中存在,取2个包含1的整数

      那么按照上面的需求,我们的框架的运行结果应为:"123","15"

      分析上面的需求,我们需要通过以下几个步骤来构建一个自定义过滤器:

    1. 识别特性,定义枚举。很容易的发现,需求中包含两个特性,分别是【长度不小于3】和【包含1】,因此,我们定义一个枚举如下
          [Flags]
          public enum DemoStringEnumType
          {
              /// <summary>
              /// 长度大于3
              /// </summary>
              LongLen = 1,
      
              /// <summary>
              /// 包含1
              /// </summary>
              HasOne = 2, 
      
              /// <summary>
              /// 无效值
              /// </summary>
              NN = 1024
          }
    2. 继承基类,构建自定义过滤器对象。基类泛型需要两个参数,分别是【待处理数据的数据类型】以及【特性的枚举类型】
          public class StringFilterCore : ComplexFilterCore<string, DemoStringEnumType>
          {
          }
    3. 开发过滤器。不难发现,需求中的过滤器,就是去【判断下一个字符串是否是整数】
         /// <summary>
          /// 是否是整数过滤器
          /// 继承IFilter
          /// </summary>
          public class IsNumberFilter : IFilter<string>
          {
      
              /// <summary>
              /// 判断字符串是否为政策
              /// </summary>
              /// <param name="item">待检验字符串</param>
              /// <returns>bool</returns>
              public bool DoFilter(string item)
              {
                  int tem; 
                  return int.TryParse(item, out tem);
              }
          }
    4. 开发识别器。
          /// <summary>
          /// 识别器
          /// 继承IEnumTypeIdentifier接口
          /// </summary>
          public class IdentifyDemoString : IEnumTypeIdentifier<string, DemoStringEnumType>
          {
      
              /// <summary>
              /// 识别对象特性
              /// </summary>
              /// <param name="item">待识别字符串</param>
              /// <returns>DemoStringEnumType</returns>
              public DemoStringEnumType IdentifyItemTypeAsEnumType(string item)
              {
                  //初始化结果
                  DemoStringEnumType result = DemoStringEnumType.NN;
      
                  //识别长度是否大于3
                  if (item.Length > 3)
                  {
                      result |= DemoStringEnumType.LongLen;
                  }
      
                  //识别是否包含1
                  if (item.Contains("1"))
                  {
                      result |= DemoStringEnumType.HasOne;
                  }
      
                  return result;
              }
      
          }
    5. 构建客户端,调试代码。
              static void Main(string[] args)
              {
                  //初始化过滤器
                  StringFilterCore demoStrFilterCore = new StringFilterCore();
      
                  //初始化 HasOne 2 LongLen 1
                  demoStrFilterCore.SetMinGetCount(DemoStringEnumType.LongLen, 1);
                  demoStrFilterCore.SetMinGetCount(DemoStringEnumType.HasOne, 2);
      
                  //注册类型识别器 识别特性 DemoStringEnumType
                  demoStrFilterCore.RegistEnumTypeIdentifier(new IdentifyDemoString());
      
                  //添加过滤器 过滤掉不是整数的字符串
                  demoStrFilterCore.AddFilter(new DemoStringContentFilter());
      
                  //初始化数据源
                  var ls = new List<string> { "123", "246", "b", "15", "16", "a32" };
      
                  //执行过滤
                  var result = demoStrFilterCore.GetFilteredResult(ls);
      
                  //打印结果
                  Console.WriteLine(string.Join(",", result.Keys));
      
                  Console.ReadKey();
              }

    收获

      抽象出通用的部分,让开发人员只关注于业务是框架存在的一大必要因素。本文提出的过滤方案具有很高的扩展性,有兴趣的同学可以下载demo研究下。

  • 相关阅读:
    转载:linux or unit 连接 windows的远程桌面-rdesktop(略有修改)
    Excel技巧
    Linux实用配置(ubuntu)
    转载:VMware linux 虚拟机中修改MAC地址
    windows技巧
    cdoj1099
    hdu1160(问题)
    c#学习笔记
    hdu1176
    qsort(),sort() scanf();
  • 原文地址:https://www.cnblogs.com/SmallZL/p/4262948.html
Copyright © 2011-2022 走看看