• 【设计模式】过滤器模式(Filter Pattern)


    过滤器模式属于结构型模式,但它并不属于我们常说的二十三种设计模式。主要是以相对解耦的方式来过滤一组对象。



    过滤器模式的介绍

    ​ 过滤器模式(Filter Pattern)或称标准模式( Criteria Pattern),其目的是通过逻辑运算以解耦的方式,运用一个或多个标准来过滤一个对象列表。

    优点

    • 过滤器结构清晰,耦合低

    应用场景

    • 需要对数据进行过滤或加工处理,但又不想与业务代码耦合的场景



    过滤器模式的使用

    ​ 举例:创建一组员工对象,使用年龄、性别等条件来过滤人员。

    类图

    image-20221123215131560



    实现方法

    第一步,创建员工类

    员工类

    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 ? "男" : "保密") +
                    ", 年龄=" + 年龄 +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    第二步,创建过滤器接口

    过滤器

    package 设计模式.结构型模式.过滤器模式.过滤器;
    
    import 设计模式.结构型模式.过滤器模式.员工;
    
    import java.util.List;
    
    public interface 过滤器 {
        List<员工> 满足标准(List<员工> 员工列表);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    第三步,编写多个条件类

    男性满足标准

    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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    女性满足标准

    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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    年龄满足标准

    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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    共同满足标准

    package 设计模式.结构型模式.过滤器模式.过滤器;
    
    import 设计模式.结构型模式.过滤器模式.员工;
    
    import java.util.List;
    
    public class 共同满足标准 implements 过滤器 {
    
        public 过滤器 标准一;
        public 过滤器 标准二;
    
        public 共同满足标准(过滤器 标准一, 过滤器 标准二) {
            this.标准一 = 标准一;
            this.标准二 = 标准二;
        }
    
        @Override
        public List<员工> 满足标准(List<员工> 员工列表) {
            return 标准二.满足标准(标准一.满足标准(员工列表));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    任意满足标准

    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 满足标准列表一;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第四步,编写测试类测试

    测试类

    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 员工列表;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    测试结果

    过滤前的人员列表:
    员工{姓名='一号测试人员', 性别=, 年龄=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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    image-20221123215808153

  • 相关阅读:
    Spring 项目快速整合 Hibernate
    如何在搜索引擎中应用AI大语言模型,提高企业生产力?
    聊聊ChatGLM-6B的源码分析
    银行基于云原生架构下的 DevOps 建设实践经验
    PyCharm高校固定资产管理系统django-python+vue
    排序算法总结
    创邻科技Galaxybase分享Part1: 图数据库和主数据管理有什么关系?
    每日一练 | 华为认证真题练习Day120
    分析高数值孔径物镜的聚焦
    proemtheus TSL加密认证
  • 原文地址:https://blog.csdn.net/weixin_45634261/article/details/128008853