过滤器模式属于结构型模式,但它并不属于我们常说的二十三种设计模式。主要是以相对解耦的方式来过滤一组对象。
文章目录
- 过滤器模式的介绍
- 优点
- 应用场景
- 过滤器模式的使用
- 类图
- 实现方法
- 第一步,创建员工类
- 第二步,创建过滤器接口
- 第三步,编写多个条件类
- 第四步,编写测试类测试
过滤器模式的介绍
过滤器模式(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 年龄;
}
@Override
public 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 过滤器 {
@Override
public List<员工> 满足标准(List<员工> 员工列表) {
// 先把数据转为流,在流中留下所有性别为0的对象,然后再转为List
return 员工列表.stream().filter(人员->人员.获取性别() == 0).collect(Collectors.toList());
}
}
女性满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;
import 设计模式.结构型模式.过滤器模式.员工;
import java.util.List;
import java.util.stream.Collectors;
public class 女性满足标准 implements 过滤器 {
@Override
public List<员工> 满足标准(List<员工> 员工列表) {
// 先把数据转为流,在流中留下所有性别为1的对象,然后再转为List
return 员工列表.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.比较器 = 比较器;
}
@Override
public List<员工> 满足标准(List<员工> 员工列表) {
return 员工列表.stream().filter(人员->比较器.比较(人员.获取年龄())).collect(Collectors.toList());
}
}
共同满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;
import 设计模式.结构型模式.过滤器模式.员工;
import java.util.List;
public class 共同满足标准 implements 过滤器 {
public 过滤器 标准一;
public 过滤器 标准二;
public 共同满足标准(过滤器 标准一, 过滤器 标准二) {
this.标准一 = 标准一;
this.标准二 = 标准二;
}
@Override
public List<员工> 满足标准(List<员工> 员工列表) {
return 标准二.满足标准(标准一.满足标准(员工列表));
}
}
任意满足标准
package 设计模式.结构型模式.过滤器模式.过滤器;
import 设计模式.结构型模式.过滤器模式.员工;
import java.util.List;
public class 任意满足标准 implements 过滤器 {
public 过滤器 标准一;
public 过滤器 标准二;
public 任意满足标准(过滤器 标准一, 过滤器 标准二) {
this.标准一 = 标准一;
this.标准二 = 标准二;
}
@Override
public 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 年龄满足标准.比较接口() {
@Override
public boolean 比较(Integer 目标年龄) {
// 目标年龄大于18
return 目标年龄 >= 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