赞
踩
定义
过滤器模式(Filter Pattern)又称为标准模式 (Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过运算逻辑以解耦的方式将它们联系起来。这种类型的设计模式属于结构型模式,说白了,就是按条件筛选一组对象出来。
组成角色
过滤器模式一般有如下角色:
抽象过滤器角色(AbstractFilter):负责定义过滤器的实现接口,具体的实现还要具体过滤器角色去参与,客户端可以调用抽象过滤器角色中定义好的方法,将客户端的所有请求委派到具体的实现类去,从而让实现类去处理;
ConcreteFilter(具体过滤器角色):该角色负责具体筛选规则的逻辑实现,最后再返回一个过滤后的数据集合,标准的过滤器只对数据做过滤,当然也可以对集合中的数据做某项处理,再将处理后的集合返回;
Subject(被过滤的主体角色):一个软件系统中可以有一个或多个目标角色,在具体过滤器角色中会对指定感兴趣的目标进行处理,以确保后面的数据确实是我想要的。
示例一
有一队人,进行条件筛选,第一次筛选女性,第二次筛选成年男性,第三次筛选已知性别的人,不符合条件的不进入选中队列。
创建应用标准的类;
/** * 1. 创建一个类,在该类上应用该标准 * @author 程就人生 * @Date */ public class Person { public Person(String name, String sex, int age) { this.name = name; this.sex = sex; this.age = age; } private String name; private String sex; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } }
为标准创建接口;
- import java.util.List;
- /**
- * 2.为标准创建一个接口
- * @author 程就人生
- * @Date
- */
- public interface ICriteria {
-
- public List<Person> filter(List<Person> personList);
- }
多个标准接口实现类;
import java.util.List; /** * 3.标准接口实现类 * @author 程就人生 * @Date */ public class AddCriteria implements ICriteria { private ICriteria criteria1; private ICriteria criteria2; public AddCriteria(ICriteria criteria1, ICriteria criteria2) { this.criteria1 = criteria1; this.criteria2 = criteria2; } @Override public List<Person> filter(List<Person> personList) { List<Person> criteria = criteria1.filter(personList); return criteria2.filter(criteria); } } import java.util.List; import java.util.stream.Collectors; /** * 3.标准接口实现类 * @author 程就人生 * @Date */ public class AgeCriteria implements ICriteria{ @Override public List<Person> filter(List<Person> personList) { return personList.stream().filter(person->person.getAge() >=18 ).collect(Collectors.toList()); } } import java.util.List; import java.util.stream.Collectors; /** * 3.标准接口实现类 * @author 程就人生 * @Date */ public class FemaleCriteria implements ICriteria{ @Override public List<Person> filter(List<Person> personList) { return personList.stream().filter(person->person.getSex().equals("女")).collect(Collectors.toList()); } } import java.util.List; import java.util.stream.Collectors; /** * 3.标准接口实现类 * @author 程就人生 * @Date */ public class MaleCriteria implements ICriteria{ @Override public List<Person> filter(List<Person> personList) { return personList.stream().filter(person->person.getSex().equals("男")).collect(Collectors.toList()); } } import java.util.List; /** * 3.标准接口实现类 * @author 程就人生 * @Date */ public class OrCriteria implements ICriteria{ private ICriteria criteria1; private ICriteria criteria2; public OrCriteria(ICriteria criteria1, ICriteria criteria2) { this.criteria1 = criteria1; this.criteria2 = criteria2; } @Override public List<Person> filter(List<Person> personList) { List<Person> firstCriteriaItems = criteria1.filter(personList); List<Person> otherCriteriaItems = criteria2.filter(personList); for (Person person : otherCriteriaItems) { if(!firstCriteriaItems.contains(person)){ firstCriteriaItems.add(person); } } return firstCriteriaItems; } }
简单应用;
public static void main(String[] argo){ List<Person> personList = new ArrayList<Person>(); personList.add(new Person("张三", "女", 20)); personList.add(new Person("老张", "女", 40)); personList.add(new Person("小明", "男", 15)); personList.add(new Person("李四", "男", 30)); personList.add(new Person("王五", "男", 35)); personList.add(new Person("王麻子", "未知", 45)); // 女性 ICriteria femaleCriteria = new FemaleCriteria(); List<Person> list = femaleCriteria.filter(personList); System.out.println("女性为:" + list); // 成年男性 ICriteria maleCriteria = new MaleCriteria(); ICriteria ageCriteria = new AgeCriteria(); ICriteria addCriteria = new AddCriteria(maleCriteria, ageCriteria); list = addCriteria.filter(personList); System.out.println("成年男性:" + list); // 男性或者女性 ICriteria orCriteria = new OrCriteria(maleCriteria, femaleCriteria); list = orCriteria.filter(personList); System.out.println("男性或者女性为:" + list); }
运行结果
- 女性为:[Person [name=张三, sex=女, age=20], Person [name=老张, sex=女, age=40]]
- 成年男性:[Person [name=李四, sex=男, age=30], Person [name=王五, sex=男, age=35]]
- 男性或者女性为:[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]]
示例二
以垃圾分类为例进行说明,使用不同的垃圾桶进行垃圾分类过滤,“垃圾” 就是我们的被过滤的角色,垃圾桶可以充当我们的绝体过滤器角色,
首先是 “垃圾” 类,也就是我们的被过滤的主体角色:
public class Rubbish { private String name; // 垃圾名称 private boolean isHarm; // 是否有害垃圾 private boolean isRecycled; // 是否可回收 private boolean isDry; // 是否干垃圾 private boolean isWet; // 是否湿垃圾 public Rubbish(String name, boolean isHarm, boolean isRecycled, boolean isDry, boolean isWet) { this.name = name; this.isHarm = isHarm; this.isRecycled = isRecycled; this.isDry = isDry; this.isWet = isWet; } ... getter、setter省略,或者直接使用lombok }
然后是我们的过滤标准的接口,即抽象过滤器角色:
- import java.util.List;
-
- public interface Criteria {
- // 定义过滤的标准
- List<Rubbish> rubbishFilter(List<Rubbish> rubbishes);
- }
我们继续创建实现了 Criteria 接口的几个实体类:
// 干垃圾 public class DryRubbishCriteria implements Criteria{ @Override public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) { List<Rubbish> rubbishList = new ArrayList<>(); for (Rubbish rubbish: rubbishes) { // 这里只过滤出所有干垃圾 if (rubbish.isDry()) { rubbishList.add(rubbish); } } return rubbishList; } } ... // 有害垃圾 public class HarmfulRubbishCriteria implements Criteria{ @Override public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) { List<Rubbish> rubbishList = new ArrayList<>(); for (Rubbish rubbish: rubbishes) { // 这里只过滤出所有有害垃圾 if (rubbish.isHarm()) { rubbishList.add(rubbish); } } return rubbishList; } } ... // 可回收垃圾 public class RecycledRubbishCriteria implements Criteria{ @Override public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) { List<Rubbish> rubbishList = new ArrayList<>(); for (Rubbish rubbish: rubbishes) { // 这里只过滤出所有可回收垃圾 if (rubbish.isRecycled()) { rubbishList.add(rubbish); } } return rubbishList; } } ... // 湿垃圾 public class WetRubbishCriteria implements Criteria{ @Override public List<Rubbish> rubbishFilter(List<Rubbish> rubbishes) { List<Rubbish> rubbishList = new ArrayList<>(); for (Rubbish rubbish: rubbishes) { // 这里只过滤出所有湿垃圾 if (rubbish.isWet()) { rubbishList.add(rubbish); } } return rubbishList; } }
使用不同的标准(Criteria)来过滤 Rubbish 对象的列表:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // 原始数据集合 List<Rubbish> rubbishList = new ArrayList<>(); rubbishList.add(new Rubbish("果壳", false, false, true, false)); rubbishList.add(new Rubbish("陶瓷", false, false, true, false)); rubbishList.add(new Rubbish("菜根菜叶", false, false, false, true)); rubbishList.add(new Rubbish("果皮", false, false, false, true)); rubbishList.add(new Rubbish("水银温度计", true, false, false, false)); rubbishList.add(new Rubbish("电池", true, false, false, false)); rubbishList.add(new Rubbish("灯泡", true, false, false, false)); rubbishList.add(new Rubbish("废纸塑料", false, true, false, false)); rubbishList.add(new Rubbish("金属和布料", false, true, false, false)); rubbishList.add(new Rubbish("玻璃", false, true, false, false)); // 四种不同的过滤标准 Criteria dryRubbishCriteria = new DryRubbishCriteria(); Criteria wetRubbishCriteria = new WetRubbishCriteria(); Criteria harmfulRubbishCriteria = new HarmfulRubbishCriteria(); Criteria recycledRubbishCriteria = new RecycledRubbishCriteria(); System.out.println("干垃圾: "); printRubbishes(dryRubbishCriteria.rubbishFilter(rubbishList)); System.out.println("湿垃圾: "); printRubbishes(wetRubbishCriteria.rubbishFilter(rubbishList)); System.out.println("有害垃圾: "); printRubbishes(harmfulRubbishCriteria.rubbishFilter(rubbishList)); System.out.println("可回收垃圾: "); printRubbishes(recycledRubbishCriteria.rubbishFilter(rubbishList)); } private static void printRubbishes(List<Rubbish> rubbishes) { for (Rubbish rubbish: rubbishes) { System.out.println(rubbish); } } }
结果如下
干垃圾: Rubbish{name='果壳', isHarm=false, isRecycled=false, isDry=true, isWet=false} Rubbish{name='陶瓷', isHarm=false, isRecycled=false, isDry=true, isWet=false} 湿垃圾: Rubbish{name='菜根菜叶', isHarm=false, isRecycled=false, isDry=false, isWet=true} Rubbish{name='果皮', isHarm=false, isRecycled=false, isDry=false, isWet=true} 有害垃圾: Rubbish{name='水银温度计', isHarm=true, isRecycled=false, isDry=false, isWet=false} Rubbish{name='电池', isHarm=true, isRecycled=false, isDry=false, isWet=false} Rubbish{name='灯泡', isHarm=true, isRecycled=false, isDry=false, isWet=false} 可回收垃圾: Rubbish{name='废纸塑料', isHarm=false, isRecycled=true, isDry=false, isWet=false} Rubbish{name='金属和布料', isHarm=false, isRecycled=true, isDry=false, isWet=false} Rubbish{name='玻璃', isHarm=false, isRecycled=true, isDry=false, isWet=false}
过滤器模式的特点:
可插拔:过滤器的设计概念要求其是支持可插拔设计的;
有序性:过滤器是被设计为一组组的过滤装置,要实现数据过滤,就必须有顺序性要求,比如我们要设计编解码过滤器,用户请求过来的 xml 数据会优先通过 xml2json 过滤器进行数据处理,完了再在响应发出前进行相应的 json2xml 过滤处理,以保证客户端交互以 xml 数据格式为准的同时系统内部数据交互还是维持 json 格式不变;
过滤器的独立性:每种过滤器必须是独立的实体,其状态不受其它过滤器的影响,每个过滤器都有自己独立的数据输入输出接口,只要各个过滤器之间传送的数据遵守共同的规约就可以相连接。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。