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

news2024/11/16 13:41:42

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

文章目录

  • 过滤器模式的介绍
    • 优点
    • 应用场景
  • 过滤器模式的使用
    • 类图
    • 实现方法
      • 第一步,创建员工类
      • 第二步,创建过滤器接口
      • 第三步,编写多个条件类
      • 第四步,编写测试类测试



过滤器模式的介绍

​ 过滤器模式(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 ? "男" : "保密") +
                ", 年龄=" + 年龄 +
                '}';
    }
}

第二步,创建过滤器接口

过滤器

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

image-20221123215808153

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/30500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何部署商城项目

如何部署商城项目 1.导入数据库 ​ 注意&#xff1a;先保证数据库开启了远程访问&#xff08;见数据库安装和配置笔记&#xff09;。 1.1设置数据库服务器编码 ​ vi /etc/my.cnf ​ 在[mysqld]下面添加 character_set_serverutf8 init_connectSET NAMES utf81.2打开本地…

RK3399平台开发系列讲解(中断篇)中断控制器(Generic Interrupt Controller)

🚀返回专栏总目录 文章目录 一、GIC硬件的实现形态二、主要的功能块三、中断类型四、中断状态沉淀、分享、成长,让自己和他人都能有所收获!😄 📢外围设备不是把中断请求直接发给处理器,而是发给中断控制器,由中断控制器转发给处理器。ARM公司提供了一种标准的中断控制…

NR CSI(二) the workflow of CSI report

微信同步更新欢迎关注同名modem协议笔记 本篇内容是对CSI report相关流程的整理&#xff0c;其描述主要集中在R16 38.331 38.321 38.214中&#xff0c;以实网中的一个配置开始&#xff0c;看下相关定义。 如上图实网中的配置&#xff0c;CSI-ReportConfig 对应的就是Reporting…

Cookie和Session的工作流程是什么样的?5min学懂:简易用户登录(前端+后端+数据库)

目录 前言 一、Cookie 1.1、Cookie从哪里来&#xff1f; 1.2、Cookie到哪里去&#xff1f; 二、Session 2.1、什么是sessionId? 三、Cookie和Session的区别 四、Cookie和Session的具体工作流程 五、代码实现用户登录 5.1、核心方法 5.2、代码 前言 想要了解Cookie和…

【设计模式】桥接模式(Bridge Pattern)

桥接模式属于结构型模式&#xff0c;主要解决因业务增长时滥用继承而导致的**“类爆炸”问题。桥接模式将一个树型的整体继承结构替换为由抽象的类&#xff08;抽象化角色&#xff09;组成的抽象部分和由实现接口&#xff08;实现化角色&#xff09;与实现类&#xff08;具体实…

无法访问mybatis.dto.StudengInVO-使用maven编译报错

一、问题由来 最近一次拉代码后&#xff0c;合并代码然后进行编译时出现一个问题&#xff0c;使用maven在进行编译的时候报一个错&#xff0c;无法访问mybatis.dto.StudengInVO。 突然出现这个错误让自己感觉很奇怪&#xff0c;开发工具已经使用了好几个月&#xff0c;项目也已…

SSM毕设项目 - 基于SSM的汉服文化平台网站(含源码+论文)

文章目录1 项目简介2 实现效果2.1 界面展示3 设计方案3.1 概述3.2 系统流程3.3 系统结构设计4 项目获取1 项目简介 Hi&#xff0c;各位同学好呀&#xff0c;这里是M学姐&#xff01; 今天向大家分享一个今年(2022)最新完成的毕业设计项目作品&#xff0c;【基于SSM的汉服文化…

(十三)Spring之JdbcTemplate

文章目录环境新增、删除与修改数据新增修改删除查询一个查询一个对象查询一个值查询多个对象批量操作批量添加批量修改批量删除使用回调函数使用德鲁伊连接池上一篇&#xff1a;&#xff08;十二&#xff09;Spring IoC注解式开发JdbcTemplate是Spring提供的一个JDBC模板类&…

高阶数据结构:二叉搜索树

本篇主要是在初级数据结构中介绍的二叉树的提升&#xff0c;了解二叉搜索树的特性。 文章目录 一、二叉搜索树的概念二、二叉搜索树操作 1、二叉搜索树的查找2、二叉搜索树的插入3、二叉搜索树的删除三、二叉搜索树的实现四、二叉搜索树的应用五、关于二叉树进阶面试题一、二叉…

大衣哥又有喜事了,孟文豪新作《克什克腾的眼泪》,是给他写的吗

农民歌唱家大衣哥又出新歌啦&#xff01; 就在大衣哥被谷传民起诉不久&#xff0c;互联网上面又传出新消息&#xff0c;继《火火的情怀》之后&#xff0c;大衣哥的新歌《新时代的新农民》&#xff0c;又要和大家见面了。很多人不明白&#xff0c;大衣哥不过是一个农民歌唱家&am…

Java中的反射,枚举和Lambda表达式

一. 反射 1. 反射的概述 2. 反射的使用 反射常用的类 通过反射获取Class对象 获得Class类相关的方法 使用反射创建实例对象 使用反射获取实例对象中的构造方法 通过反射获取实例对象的属性 通过反射获取实例对象的方法 3. 反射的优缺点 二. 枚举 1…

Graalvm 安装和静态编译

文章目录1、下载2、graalvm安装3、native-image工具安装3.1 安装native-image3.2 安装C编译工具4、java编译成二进制exe4.1、普通的java命令行应用4.2、Swing应用编译4.3、使用maven插件静态编译4.4、javafx应用编译1、下载 文件下载&#xff1a;https://www.graalvm.org/down…

[附源码]计算机毕业设计JAVA剧本杀门店管理系统-

[附源码]计算机毕业设计JAVA剧本杀门店管理系统- 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myb…

OBS-VirtualCam OBS的虚拟摄像头插件

OBS-VirtualCam 是OBS的一个虚拟摄像头插件&#xff0c;可以将OBS中的内容提供给一个虚拟摄像头&#xff0c;这样其它软件就可以使用这个内容了&#xff0c;这里试试这个插件功能。 1. 下载obs并安装 登录OBS Studio网站&#xff0c;下载windows版&#xff0c; 下载完成后并安装…

栈的基本操作

目录 一、什么是栈&#xff1f; 二、用单链表实现栈 三、用顺序表数组实现栈 一、什么是栈&#xff1f; 栈&#xff08;stack&#xff09;是一个先进后出&#xff08;FILO-First In Last Out&#xff09;的有序列表。 主要方法&#xff1a;入栈&#xff08;push&#xff09;…

SCA算法优化脉冲耦合神经网络的图像自动分割(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

【C语言】初识指针(终篇)

摸了一手秀发&#xff0c;发现还在~ 目录 1、指针运算 1.1指针加减整数 1.2指针减指针 1.3指针关系运算 2、二级指针 3、指针和数组 4、指针数组 前言&#xff1a; 大家好&#xff0c;我是拳击哥。上一期我们讲到了指针类型&#xff0c;指针的访问步长&#xff0c;野指针…

Redis数据类型总结

文章目录一、5种数据类型二、常用指令汇总三、应用汇总提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 一、5种数据类型 Redis 数据存储格式&#xff1a;  ● redis 自身是一个 Map ,其中所有的数据都是采用 key : value 的形式存储。  ● 数…

如何设计用户体验测试用例

一、 什么是用户体验 UE&#xff1a; User Experience 用户体验。 用户体验是指用户在使用产品过程中的个人主观感受&#xff0c;即用户在使用一个产品之前、使用过程中、使用后的整体感受&#xff0c;包括行为、情感、喜好、生理和心里反应、成就等各个方面。 通俗的讲用户体…

希望所有计算机学生都知道这些宝藏网站

GitHub GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 作为开源代码库以及版本控制系统&#xff0c;Github拥有超过900万开发者用户。随着越来越多的应用程序转移到了云上&#xff0c;Github已…