当前位置:   article > 正文

设计模式之过滤器模式_过滤器是什么设计模式

过滤器是什么设计模式
  1. 定义

过滤器模式(Filter Pattern)又称为标准模式 (Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过运算逻辑以解耦的方式将它们联系起来。这种类型的设计模式属于结构型模式,说白了,就是按条件筛选一组对象出来。

  1. 组成角色

过滤器模式一般有如下角色:

  • 抽象过滤器角色(AbstractFilter):负责定义过滤器的实现接口,具体的实现还要具体过滤器角色去参与,客户端可以调用抽象过滤器角色中定义好的方法,将客户端的所有请求委派到具体的实现类去,从而让实现类去处理;

  • ConcreteFilter(具体过滤器角色):该角色负责具体筛选规则的逻辑实现,最后再返回一个过滤后的数据集合,标准的过滤器只对数据做过滤,当然也可以对集合中的数据做某项处理,再将处理后的集合返回;

  • Subject(被过滤的主体角色):一个软件系统中可以有一个或多个目标角色,在具体过滤器角色中会对指定感兴趣的目标进行处理,以确保后面的数据确实是我想要的。

  1. 示例一

有一队人,进行条件筛选,第一次筛选女性,第二次筛选成年男性,第三次筛选已知性别的人,不符合条件的不进入选中队列。

  • 创建应用标准的类;

  1. /**
  2. * 1. 创建一个类,在该类上应用该标准
  3. * @author 程就人生
  4. * @Date
  5. */
  6. public class Person {
  7. public Person(String name, String sex, int age) {
  8. this.name = name;
  9. this.sex = sex;
  10. this.age = age;
  11. }
  12. private String name;
  13. private String sex;
  14. private int age;
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. public String getSex() {
  22. return sex;
  23. }
  24. public void setSex(String sex) {
  25. this.sex = sex;
  26. }
  27. public int getAge() {
  28. return age;
  29. }
  30. public void setAge(int age) {
  31. this.age = age;
  32. }
  33. @Override
  34. public String toString() {
  35. return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
  36. }
  37. }
  • 为标准创建接口;

  1. import java.util.List;
  2. /**
  3. * 2.为标准创建一个接口
  4. * @author 程就人生
  5. * @Date
  6. */
  7. public interface ICriteria {
  8. public List<Person> filter(List<Person> personList);
  9. }
  • 多个标准接口实现类;

  1. import java.util.List;
  2. /**
  3. * 3.标准接口实现类
  4. * @author 程就人生
  5. * @Date
  6. */
  7. public class AddCriteria implements ICriteria {
  8. private ICriteria criteria1;
  9. private ICriteria criteria2;
  10. public AddCriteria(ICriteria criteria1, ICriteria criteria2) {
  11. this.criteria1 = criteria1;
  12. this.criteria2 = criteria2;
  13. }
  14. @Override
  15. public List<Person> filter(List<Person> personList) {
  16. List<Person> criteria = criteria1.filter(personList);
  17. return criteria2.filter(criteria);
  18. }
  19. }
  20. import java.util.List;
  21. import java.util.stream.Collectors;
  22. /**
  23. * 3.标准接口实现类
  24. * @author 程就人生
  25. * @Date
  26. */
  27. public class AgeCriteria implements ICriteria{
  28. @Override
  29. public List<Person> filter(List<Person> personList) {
  30. return personList.stream().filter(person->person.getAge() >=18 ).collect(Collectors.toList());
  31. }
  32. }
  33. import java.util.List;
  34. import java.util.stream.Collectors;
  35. /**
  36. * 3.标准接口实现类
  37. * @author 程就人生
  38. * @Date
  39. */
  40. public class FemaleCriteria implements ICriteria{
  41. @Override
  42. public List<Person> filter(List<Person> personList) {
  43. return personList.stream().filter(person->person.getSex().equals("女")).collect(Collectors.toList());
  44. }
  45. }
  46. import java.util.List;
  47. import java.util.stream.Collectors;
  48. /**
  49. * 3.标准接口实现类
  50. * @author 程就人生
  51. * @Date
  52. */
  53. public class MaleCriteria implements ICriteria{
  54. @Override
  55. public List<Person> filter(List<Person> personList) {
  56. return personList.stream().filter(person->person.getSex().equals("男")).collect(Collectors.toList());
  57. }
  58. }
  59. import java.util.List;
  60. /**
  61. * 3.标准接口实现类
  62. * @author 程就人生
  63. * @Date
  64. */
  65. public class OrCriteria implements ICriteria{
  66. private ICriteria criteria1;
  67. private ICriteria criteria2;
  68. public OrCriteria(ICriteria criteria1, ICriteria criteria2) {
  69. this.criteria1 = criteria1;
  70. this.criteria2 = criteria2;
  71. }
  72. @Override
  73. public List<Person> filter(List<Person> personList) {
  74. List<Person> firstCriteriaItems = criteria1.filter(personList);
  75. List<Person> otherCriteriaItems = criteria2.filter(personList);
  76. for (Person person : otherCriteriaItems) {
  77. if(!firstCriteriaItems.contains(person)){
  78. firstCriteriaItems.add(person);
  79. }
  80. }
  81. return firstCriteriaItems;
  82. }
  83. }
  • 简单应用;

  1. public static void main(String[] argo){
  2. List<Person> personList = new ArrayList<Person>();
  3. personList.add(new Person("张三", "女", 20));
  4. personList.add(new Person("老张", "女", 40));
  5. personList.add(new Person("小明", "男", 15));
  6. personList.add(new Person("李四", "男", 30));
  7. personList.add(new Person("王五", "男", 35));
  8. personList.add(new Person("王麻子", "未知", 45));
  9. // 女性
  10. ICriteria femaleCriteria = new FemaleCriteria();
  11. List<Person> list = femaleCriteria.filter(personList);
  12. System.out.println("女性为:" + list);
  13. // 成年男性
  14. ICriteria maleCriteria = new MaleCriteria();
  15. ICriteria ageCriteria = new AgeCriteria();
  16. ICriteria addCriteria = new AddCriteria(maleCriteria, ageCriteria);
  17. list = addCriteria.filter(personList);
  18. System.out.println("成年男性:" + list);
  19. // 男性或者女性
  20. ICriteria orCriteria = new OrCriteria(maleCriteria, femaleCriteria);
  21. list = orCriteria.filter(personList);
  22. System.out.println("男性或者女性为:" + list);
  23. }
  • 运行结果

  1. 女性为:[Person [name=张三, sex=女, age=20], Person [name=老张, sex=女, age=40]]
  2. 成年男性:[Person [name=李四, sex=男, age=30], Person [name=王五, sex=男, age=35]]
  3. 男性或者女性为:[Person [name=小明, sex=男, age=15], Person [name=李四, sex=男, age=30], Person [name=王五, sex=男, age=35], Person [name=张三, sex=女, age=20], Person [name=老张, sex=女, age=40]]
  1. 示例二

垃圾分类为例进行说明,使用不同的垃圾桶进行垃圾分类过滤,“垃圾” 就是我们的被过滤的角色,垃圾桶可以充当我们的绝体过滤器角色,

  • 首先是 “垃圾” 类,也就是我们的被过滤的主体角色:

  1. public class Rubbish {
  2. private String name; // 垃圾名称
  3. private boolean isHarm; // 是否有害垃圾
  4. private boolean isRecycled; // 是否可回收
  5. private boolean isDry; // 是否干垃圾
  6. private boolean isWet; // 是否湿垃圾
  7. public Rubbish(String name, boolean isHarm, boolean isRecycled, boolean isDry, boolean isWet) {
  8. this.name = name;
  9. this.isHarm = isHarm;
  10. this.isRecycled = isRecycled;
  11. this.isDry = isDry;
  12. this.isWet = isWet;
  13. }
  14. ... getter、setter省略,或者直接使用lombok
  15. }
  • 然后是我们的过滤标准的接口,即抽象过滤器角色:

  1. import java.util.List;
  2. public interface Criteria {
  3. // 定义过滤的标准
  4. List<Rubbish> rubbishFilter(List<Rubbish> rubbishes);
  5. }
  • 我们继续创建实现了 Criteria 接口的几个实体类:

  1. // 干垃圾
  2. public class DryRubbishCriteria implements Criteria{
  3. @Override
  4. public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) {
  5. List<Rubbish> rubbishList = new ArrayList<>();
  6. for (Rubbish rubbish: rubbishes) {
  7. // 这里只过滤出所有干垃圾
  8. if (rubbish.isDry()) {
  9. rubbishList.add(rubbish);
  10. }
  11. }
  12. return rubbishList;
  13. }
  14. }
  15. ...
  16. // 有害垃圾
  17. public class HarmfulRubbishCriteria implements Criteria{
  18. @Override
  19. public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) {
  20. List<Rubbish> rubbishList = new ArrayList<>();
  21. for (Rubbish rubbish: rubbishes) {
  22. // 这里只过滤出所有有害垃圾
  23. if (rubbish.isHarm()) {
  24. rubbishList.add(rubbish);
  25. }
  26. }
  27. return rubbishList;
  28. }
  29. }
  30. ...
  31. // 可回收垃圾
  32. public class RecycledRubbishCriteria implements Criteria{
  33. @Override
  34. public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) {
  35. List<Rubbish> rubbishList = new ArrayList<>();
  36. for (Rubbish rubbish: rubbishes) {
  37. // 这里只过滤出所有可回收垃圾
  38. if (rubbish.isRecycled()) {
  39. rubbishList.add(rubbish);
  40. }
  41. }
  42. return rubbishList;
  43. }
  44. }
  45. ...
  46. // 湿垃圾
  47. public class WetRubbishCriteria implements Criteria{
  48. @Override
  49. public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) {
  50. List<Rubbish> rubbishList = new ArrayList<>();
  51. for (Rubbish rubbish: rubbishes) {
  52. // 这里只过滤出所有湿垃圾
  53. if (rubbish.isWet()) {
  54. rubbishList.add(rubbish);
  55. }
  56. }
  57. return rubbishList;
  58. }
  59. }
  • 使用不同的标准(Criteria)来过滤 Rubbish 对象的列表:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Main {
  4. public static void main(String[] args) {
  5. // 原始数据集合
  6. List<Rubbish> rubbishList = new ArrayList<>();
  7. rubbishList.add(new Rubbish("果壳", false, false, true, false));
  8. rubbishList.add(new Rubbish("陶瓷", false, false, true, false));
  9. rubbishList.add(new Rubbish("菜根菜叶", false, false, false, true));
  10. rubbishList.add(new Rubbish("果皮", false, false, false, true));
  11. rubbishList.add(new Rubbish("水银温度计", true, false, false, false));
  12. rubbishList.add(new Rubbish("电池", true, false, false, false));
  13. rubbishList.add(new Rubbish("灯泡", true, false, false, false));
  14. rubbishList.add(new Rubbish("废纸塑料", false, true, false, false));
  15. rubbishList.add(new Rubbish("金属和布料", false, true, false, false));
  16. rubbishList.add(new Rubbish("玻璃", false, true, false, false));
  17. // 四种不同的过滤标准
  18. Criteria dryRubbishCriteria = new DryRubbishCriteria();
  19. Criteria wetRubbishCriteria = new WetRubbishCriteria();
  20. Criteria harmfulRubbishCriteria = new HarmfulRubbishCriteria();
  21. Criteria recycledRubbishCriteria = new RecycledRubbishCriteria();
  22. System.out.println("干垃圾: ");
  23. printRubbishes(dryRubbishCriteria.rubbishFilter(rubbishList));
  24. System.out.println("湿垃圾: ");
  25. printRubbishes(wetRubbishCriteria.rubbishFilter(rubbishList));
  26. System.out.println("有害垃圾: ");
  27. printRubbishes(harmfulRubbishCriteria.rubbishFilter(rubbishList));
  28. System.out.println("可回收垃圾: ");
  29. printRubbishes(recycledRubbishCriteria.rubbishFilter(rubbishList));
  30. }
  31. private static void printRubbishes(List<Rubbish> rubbishes) {
  32. for (Rubbish rubbish: rubbishes) {
  33. System.out.println(rubbish);
  34. }
  35. }
  36. }
  • 结果如下

  1. 干垃圾:
  2. Rubbish{name='果壳', isHarm=false, isRecycled=false, isDry=true, isWet=false}
  3. Rubbish{name='陶瓷', isHarm=false, isRecycled=false, isDry=true, isWet=false}
  4. 湿垃圾:
  5. Rubbish{name='菜根菜叶', isHarm=false, isRecycled=false, isDry=false, isWet=true}
  6. Rubbish{name='果皮', isHarm=false, isRecycled=false, isDry=false, isWet=true}
  7. 有害垃圾:
  8. Rubbish{name='水银温度计', isHarm=true, isRecycled=false, isDry=false, isWet=false}
  9. Rubbish{name='电池', isHarm=true, isRecycled=false, isDry=false, isWet=false}
  10. Rubbish{name='灯泡', isHarm=true, isRecycled=false, isDry=false, isWet=false}
  11. 可回收垃圾:
  12. Rubbish{name='废纸塑料', isHarm=false, isRecycled=true, isDry=false, isWet=false}
  13. Rubbish{name='金属和布料', isHarm=false, isRecycled=true, isDry=false, isWet=false}
  14. Rubbish{name='玻璃', isHarm=false, isRecycled=true, isDry=false, isWet=false}
  1. 过滤器模式的特点:

  • 可插拔:过滤器的设计概念要求其是支持可插拔设计的;

  • 有序性:过滤器是被设计为一组组的过滤装置,要实现数据过滤,就必须有顺序性要求,比如我们要设计编解码过滤器,用户请求过来的 xml 数据会优先通过 xml2json 过滤器进行数据处理,完了再在响应发出前进行相应的 json2xml 过滤处理,以保证客户端交互以 xml 数据格式为准的同时系统内部数据交互还是维持 json 格式不变;

  • 过滤器的独立性:每种过滤器必须是独立的实体,其状态不受其它过滤器的影响,每个过滤器都有自己独立的数据输入输出接口,只要各个过滤器之间传送的数据遵守共同的规约就可以相连接。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/482035
推荐阅读
相关标签
  

闽ICP备14008679号