过滤器模式属于结构型模式,但它并不属于我们常说的二十三种设计模式。主要是以相对解耦的方式来过滤一组对象。
过滤器模式(Filter Pattern)或称标准模式( Criteria Pattern),其目的是通过逻辑运算以解耦的方式,运用一个或多个标准来过滤一个对象列表。
举例:创建一组员工对象,使用年龄、性别等条件来过滤人员。
员工类
package 设计模式.结构型模式.过滤器模式;public class 员工 {private String 姓名;private Byte 性别 = 2; // 0为男 1为女 2为保密private Integer 年龄;public 员工(String 姓名, Byte 性别, Integer 年龄) {this.姓名 = 姓名;this.性别 = 性别;this.年龄 = 年龄;}public String 获取姓名() {return 姓名;}public Byte 获取性别() {return 性别;}public Integer 获取年龄() {return 年龄;}@Overridepublic String toString() {return "员工{" +"姓名='" + 姓名 + '\'' +", 性别=" + (性别 == 1 ? "女" : 性别 == 0 ? "男" : "保密") +", 年龄=" + 年龄 +'}';}
}
过滤器
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;public interface 过滤器 {List<员工> 满足标准(List<员工> 员工列表);
}
男性满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;
import java.util.stream.Collectors;public class 男性满足标准 implements 过滤器 {@Overridepublic List<员工> 满足标准(List<员工> 员工列表) {// 先把数据转为流,在流中留下所有性别为0的对象,然后再转为Listreturn 员工列表.stream().filter(人员->人员.获取性别() == 0).collect(Collectors.toList());}
}
女性满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;
import java.util.stream.Collectors;public class 女性满足标准 implements 过滤器 {@Overridepublic List<员工> 满足标准(List<员工> 员工列表) {// 先把数据转为流,在流中留下所有性别为1的对象,然后再转为Listreturn 员工列表.stream().filter(人员->人员.获取性别() == 1).collect(Collectors.toList());}
}
年龄满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;
import java.util.stream.Collectors;public class 年龄满足标准 implements 过滤器 {// 回调接口public interface 比较接口{boolean 比较(Integer 目标年龄);}private 比较接口 比较器;public 年龄满足标准(比较接口 比较器) {this.比较器 = 比较器;}@Overridepublic List<员工> 满足标准(List<员工> 员工列表) {return 员工列表.stream().filter(人员->比较器.比较(人员.获取年龄())).collect(Collectors.toList());}
}
共同满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;public class 共同满足标准 implements 过滤器 {public 过滤器 标准一;public 过滤器 标准二;public 共同满足标准(过滤器 标准一, 过滤器 标准二) {this.标准一 = 标准一;this.标准二 = 标准二;}@Overridepublic List<员工> 满足标准(List<员工> 员工列表) {return 标准二.满足标准(标准一.满足标准(员工列表));}
}
任意满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;import 设计模式.结构型模式.过滤器模式.员工;import java.util.List;public class 任意满足标准 implements 过滤器 {public 过滤器 标准一;public 过滤器 标准二;public 任意满足标准(过滤器 标准一, 过滤器 标准二) {this.标准一 = 标准一;this.标准二 = 标准二;}@Overridepublic List<员工> 满足标准(List<员工> 员工列表) {List<员工> 满足标准列表一 = 标准一.满足标准(员工列表);List<员工> 满足标准列表二 = 标准二.满足标准(员工列表);for (员工 人员 : 满足标准列表二) {// 如果满足标准列表二中的人员不存在于满足标准列表一,那就添加到满足标准列表一if(!满足标准列表一.contains(人员)){满足标准列表一.add(人员);}}return 满足标准列表一;}
}
测试类
package 设计模式.结构型模式.过滤器模式;import 设计模式.结构型模式.过滤器模式.过滤器.*;import java.util.ArrayList;
import java.util.List;public class 测试类 {public static void main(String[] args) {// 创建员工列表List<员工> 员工列表 = 读取员工列表();List<员工> 测试列表 = new ArrayList<>();System.out.println("过滤前的人员列表:");员工列表.forEach(System.out::println);System.out.println("\n");// 进行年龄比较过滤器 年龄过滤器 = new 年龄满足标准(new 年龄满足标准.比较接口() {@Overridepublic boolean 比较(Integer 目标年龄) {// 目标年龄大于18return 目标年龄 >= 25;}});测试列表 = 年龄过滤器.满足标准(员工列表);System.out.println("年龄大于或等于25岁的人员列表:");测试列表.forEach(System.out::println);System.out.println("\n");// 满足上面的年龄比较的男性员工过滤器 共同满足过滤器 = new 共同满足标准(年龄过滤器, new 女性满足标准());测试列表 = 共同满足过滤器.满足标准(员工列表);System.out.println("经过年龄标准和女性标准共同过滤后的人员列表:");测试列表.forEach(System.out::println);System.out.println("\n");// 满足上面年龄比较或性别为1的员工过滤器 任意满足过滤器 = new 任意满足标准(年龄过滤器, new 女性满足标准());测试列表 = 任意满足过滤器.满足标准(员工列表);System.out.println("满足年龄标准或性别为女性的人员列表:");测试列表.forEach(System.out::println);}static List<员工> 读取员工列表(){// 模拟读取员工数据List<员工> 员工列表 = new ArrayList<>();员工列表.add(new 员工("一号测试人员", (byte) 0,26));员工列表.add(new 员工("二号测试人员", (byte) 1,18));员工列表.add(new 员工("三号测试人员", (byte) 0,35));员工列表.add(new 员工("四号测试人员", (byte) 1,17));员工列表.add(new 员工("五号测试人员", (byte) 1,25));员工列表.add(new 员工("六号测试人员", (byte) 0,31));员工列表.add(new 员工("七号测试人员", (byte) 0,22));return 员工列表;}
}
测试结果
过滤前的人员列表:
员工{姓名='一号测试人员', 性别=男, 年龄=26}
员工{姓名='二号测试人员', 性别=女, 年龄=18}
员工{姓名='三号测试人员', 性别=男, 年龄=35}
员工{姓名='四号测试人员', 性别=女, 年龄=17}
员工{姓名='五号测试人员', 性别=女, 年龄=25}
员工{姓名='六号测试人员', 性别=男, 年龄=31}
员工{姓名='七号测试人员', 性别=男, 年龄=22}年龄大于或等于25岁的人员列表:
员工{姓名='一号测试人员', 性别=男, 年龄=26}
员工{姓名='三号测试人员', 性别=男, 年龄=35}
员工{姓名='五号测试人员', 性别=女, 年龄=25}
员工{姓名='六号测试人员', 性别=男, 年龄=31}经过年龄标准和女性标准共同过滤后的人员列表:
员工{姓名='五号测试人员', 性别=女, 年龄=25}满足年龄标准或性别为女性的人员列表:
员工{姓名='一号测试人员', 性别=男, 年龄=26}
员工{姓名='三号测试人员', 性别=男, 年龄=35}
员工{姓名='五号测试人员', 性别=女, 年龄=25}
员工{姓名='六号测试人员', 性别=男, 年龄=31}
员工{姓名='二号测试人员', 性别=女, 年龄=18}
员工{姓名='四号测试人员', 性别=女, 年龄=17}Process finished with exit code 0