设计模式-过滤器模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • Java中的过滤器介绍
    • 代码示例
      • Java实现过滤器模式
      • Python实现过滤器模式
    • 过滤器模式在spring中的应用


模式介绍

过滤器模式是一种设计模式,它允许开发人员使用不同的标准来过滤一组对象。这种模式是通过运算逻辑以解耦的方式将它们联系起来。在结构上,这种类型的设计模式属于结构型模式,即按条件筛选一组对象出来。

过滤器模式的组成部分包括:

  1. 抽象过滤器角色(AbstractFilter):负责定义过滤器的实现接口。具体的实现还需要具体过滤器角色去参与。客户端可以调用抽象过滤器角色中定义好的方法,将客户端的所有请求委派到具体的实现类去,从而让实现类去处理。
  2. 具体过滤器角色(ConcreteFilter):该角色负责具体筛选规则的逻辑实现,最后再返回一个过滤后的数据集合。标准的过滤器只对数据做过滤,当然也可以对集合中的数据做某项处理,再将处理后的集合返回。
  3. 被过滤的主体角色(Subject):一个软件系统中可以有一个或多个目标角色,在具体过滤器角色中会对指定感兴趣的目标进行处理,以确保后面的数据确实是我想要的。

此外,根据具体的使用场景,还可以扩展出过滤器链(FilterChain)的概念,将多个过滤器按照一定的顺序组合起来,形成一个过滤器链,依次对数据进行过滤。

总的来说,过滤器模式的核心思想是将筛选条件和数据集合分离,使得二者可以独立变化而互不影响。这种模式有助于提高系统的灵活性和可维护性。

在这里插入图片描述

模式特点

过滤器模式的优点包括:

  1. 灵活性:通过定义不同的过滤器实现类和谓词,可以灵活地对数据集合进行过滤,得到符合不同条件的子集。
  2. 可扩展性:可以轻松地添加、组合和重用不同的过滤器,扩展过滤器的功能。
  3. 简单性:将数据集合和过滤器分开,使得代码更加清晰和易于维护。

然而,过滤器模式也存在一些缺点:

  1. 性能问题:当数据集合非常大时,每次过滤都需要遍历整个数据集合,可能导致性能问题。
  2. 配置复杂性:当需要组合多个过滤器时,可能需要编写大量的配置代码,增加了代码的复杂性。

在这里插入图片描述

应用场景

过滤器模式的应用场景主要包括:

  1. 数据过滤:通过过滤器可以实现对数据的清晰化、加密、去重、去重复等处理,有效降低数据处理的时间和成本。
  2. 网络安全:过滤器可以识别一些有害的请求或数据包,对其进行屏蔽或加工,提高网络的安全性。
  3. 性能优化:通过过滤器可以对数据进行压缩、加速、减少不必要的重复等优化处理,提高系统的性能。
  4. 内容控制:过滤器可以识别出恶意或不当的内容,加以过滤或替换,维护良好的内容生态。
  5. 业务逻辑与处理逻辑解耦:当需要对数据进行特殊处理,且处理逻辑与业务逻辑需要解耦时,可以使用过滤器模式。例如,需要对人员进行过滤,同时不想与业务代码耦合。可以定义一个过滤接口DataFilter,并增加其实现类DataFilterByOne、DataFilterByTwo、DataFilterByThree,内部增加过滤逻辑。消费者直接调用具体过滤类即可。

在这里插入图片描述

Java中的过滤器介绍

在Java中,"过滤器"的概念在不同的上下文中有不同的含义。以下是一些常见的情境和相关的Java过滤器概念:

  1. Servlet过滤器(Filter in Servlet API)

    • 在Java Web开发中,Servlet过滤器是一个设计模式,允许你在请求到达Servlet或JSP之前或之后执行某些操作。
    • 过滤器通常用于执行以下任务:
      • 字符编码设置。
      • 日志记录。
      • 认证和授权。
      • 数据压缩。
      • 缓存。
    • 创建一个过滤器,你需要实现javax.servlet.Filter接口,并重写doFilter方法。
  2. Java Stream API中的过滤(Filter in Java Stream API)

    • 在Java 8及以后的版本中,Stream API提供了一个filter方法,用于从原始数据源中筛选出满足特定条件的元素。
    • 例如,你可以使用filter方法来筛选出一个整数列表中的所有偶数。
  3. 自定义注解过滤器(Custom Annotation-based Filters)

    • 在Spring框架中,你可以创建自定义的注解过滤器,这些过滤器可以基于某些条件来决定是否继续处理请求或将其转发给其他组件。
  4. 数据库查询中的过滤(Filter in Database Queries)

    • 在执行数据库查询时,你可能会使用某种形式的"过滤",以只获取你感兴趣的数据。这通常在SQL查询中使用WHERE子句完成。
  5. 第三方库和框架中的过滤器

    • 许多第三方库和框架在它们自己的API中实现了过滤的概念。例如,MyBatis-Plus有一个强大的查询构造器,其中包括过滤条件的功能。
  6. 其他上下文

    • 在不同的框架、库或应用程序中,"过滤器"可能有其特定的用途和实现方式。

如果你有关于特定上下文或技术的具体问题,请提供更多细节,我会为你提供更详细的解答。

在这里插入图片描述

代码示例

Java实现过滤器模式

以下是一个简单的Java实现过滤器模式的示例:

import java.util.ArrayList;
import java.util.List;

// 抽象过滤器角色
interface Filter {
    boolean isAccepted(Object obj);
}

// 具体过滤器角色1
class ConcreteFilter1 implements Filter {
    private String name;

    public ConcreteFilter1(String name) {
        this.name = name;
    }

    @Override
    public boolean isAccepted(Object obj) {
        return ((String) obj).startsWith(name);
    }
}

// 具体过滤器角色2
class ConcreteFilter2 implements Filter {
    private String name;

    public ConcreteFilter2(String name) {
        this.name = name;
    }

    @Override
    public boolean isAccepted(Object obj) {
        return ((String) obj).endsWith(name);
    }
}

// 被过滤的主体角色
class Subject {
    private List<String> items = new ArrayList<>();
    private List<Filter> filters = new ArrayList<>();

    public void addItem(String item) {
        items.add(item);
    }

    public void addFilter(Filter filter) {
        filters.add(filter);
    }

    public List<String> getItems() {
        List<String> result = new ArrayList<>();
        for (String item : items) {
            for (Filter filter : filters) {
                if (filter.isAccepted(item)) {
                    result.add(item);
                    break; // 如果一个item通过了所有filters,那么直接加入到结果集中,不必再继续遍历下去。
                }
            }
        }
        return result;
    }
}

使用示例:

public class Main {
    public static void main(String[] args) {
        Subject subject = new Subject(); // 创建被过滤的主体对象。
        subject.addItem("apple"); // 添加被过滤的主体对象。
        subject.addItem("banana"); // 添加被过滤的主体对象。
        subject.addItem("pear"); // 添加被过滤的主体对象。
        subject.addItem("grape"); // 添加被过滤的主体对象。
        subject.addItem("orange"); // 添加被过滤的主体对象。
        subject.addFilter(new ConcreteFilter1("a")); // 添加第一个具体过滤器对象。只接受以"a"开头的字符串。例如"apple"。此时被过滤的主体对象变为:[apple]。剩余的未通过的字符串:["banana", "pear", "grape", "orange"]。但是这四个对象可以接受其他过滤器的检查。因此它们不会立即被丢弃掉。例如"banana"可以接受第二个过滤器的检查,而"orange"不可以接受任何过滤器的检查。所以最后的筛选结果应该是["apple", "banana"]。因为只有这两个对象通过了所有过滤器的检查。而"pear"和"grape"没有通过所有过滤器的检查,所以最后不应该出现在结果集中。这和之前的理解可能不同,但这确实是被过滤器模式的正确应用方式。只有在当前没有被任何过滤器所接受的剩余字符串不再继续参与后面的过滤过程(也就是不在参与后续的循环),而直接丢弃掉。如果一个字符串通过了所有过滤器的检查,那么它就可以直接加入到结果集中,不必再继续遍历下去。如果一个字符串没有通过所有过滤器的检查,那么它就会一直保持下去,直到不再参与后续的过滤过程为止。因此,如果一个字符串没有通过所有过滤器的检查,那么它就会一直保持下去,直到不再参与后续的过滤过程为止。这是被过滤器模式的正确应用方式。

Python实现过滤器模式

在Python中,过滤器模式可以通过使用生成器函数来实现。生成器函数允许你编写一个函数,该函数在每次调用时生成一个新的值,而不是返回所有值。这种函数特别适合用于过滤器模式,因为你可以根据某些条件来生成或过滤值。

以下是一个Python实现过滤器模式的示例:

def filter_numbers(numbers, condition):
    """
    使用给定条件过滤数字的生成器函数。
    """
    for num in numbers:
        if condition(num):
            yield num

# 示例用法
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = filter_numbers(numbers, lambda x: x % 2 == 0)

# 输出结果
for num in even_numbers:
    print(num)

在这个示例中,filter_numbers函数接受一个数字列表和一个条件函数作为参数。条件函数是一个接受一个参数并返回布尔值的函数。在每次迭代中,如果条件函数对当前数字返回True,则该数字被生成并返回。

你可以根据需要修改条件函数来过滤不同的数字。例如,你可以使用lambda x: x > 5作为条件函数来过滤出大于5的数字。

在这里插入图片描述

过滤器模式在spring中的应用

过滤器模式在Spring框架中有多种应用场景,其中最常见的是在Web应用中用于处理请求和响应的过滤。Spring提供了一些内置的过滤器,例如拦截器和过滤器,你可以通过实现这些过滤器来对请求和响应进行预处理或后处理。

下面是一个使用Spring拦截器的示例:

  1. 创建一个实现HandlerInterceptor接口的类:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行的操作
        // 例如,检查请求的权限或身份验证
        return true; // 返回true表示继续处理请求,返回false表示中止请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后执行的操作
        // 例如,记录日志或修改响应内容
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求处理完成之后执行的操作
        // 例如,清理资源或关闭数据库连接
    }
}
  1. 在Spring配置文件中注册拦截器:
<bean id="myInterceptor" class="com.example.MyInterceptor" />

<bean class="org.springframework.web.servlet.handler.HandlerInterceptorRegistry">
    <property name="interceptors">
        <list>
            <ref bean="myInterceptor" />
        </list>
    </property>
</bean>

通过这种方式,你可以在请求处理之前、之后或完成后执行自定义的逻辑,例如权限检查、日志记录或修改响应内容等。过滤器模式在Spring中的其他应用还包括用于数据转换、验证和格式化的组件。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

XIAO ESP32S3之物体检测加入视频流

一、前言 由于XIAO ESP32S3开发套件没有显示屏配件&#xff0c;因此加入http视频流功能&#xff0c;可通过浏览器请求ESP32S3上的视频流。 二、思路 1、XIAO ESP32S3启动后通过wifi连接到AP&#xff1b; 2、启动http服务器&#xff0c;注册get_mjpeg处理函数&#xff1b; 3…

2023年中职“网络安全”——B-5:网络安全事件响应(Server2216)

B-5&#xff1a;网络安全事件响应 任务环境说明&#xff1a; 服务器场景&#xff1a;Server2216&#xff08;开放链接&#xff09; 用户名:root密码&#xff1a;123456 1、黑客通过网络攻入本地服务器&#xff0c;通过特殊手段在系统中建立了多个异常进程&#xff0c;找出启…

【Pytorch】学习记录分享8——PyTorch自然语言处理基础-词向量模型Word2Vec

【Pytorch】学习记录分享7——PyTorch自然语言处理基础-词向量模型Word2Vec 1. 词向量模型Word2Vec)1. 如何度量这个单词的&#xff1f;2.词向量是什么样子&#xff1f;3.词向量对应的热力图&#xff1a;4.词向量模型的输入与输出![在这里插入图片描述](https://img-blog.csdni…

Java面试题及答案汇总来啦!快来领取

Java面试题及答案汇总来啦&#xff01;快来领取 还有不到两个月就要过年了&#xff0c;过完年紧接着“金三银四”招聘热季就要到了&#xff0c;在过年期间只想着吃吃喝喝玩玩&#xff0c;这习是学不了一点。那就趁着过年前这段时间开始恶补Java面试题&#xff0c;实现弯道超车吧…

ArkTS基本概念装饰器

目录 ArkTS基本概念 装饰器汇总 ArkTS基本概念 ArkTS是HarmonyOS的主力应用开发语言。 它在TypeScript&#xff08;简称TS&#xff09;的基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨…

FTP简介FTP服务器的搭建【虚拟机版】以及计算机端口的介绍

目录 一. FTP简介 二. FTP服务器的搭建【虚拟机Windows2012版】 1. 启用防火墙 2. 打开服务器管理器➡工具➡计算机管理 3. 选择本地用户与组➡新建组 4. 给组命名&#xff0c;输入描述&#xff0c;点击创建 5. 新建用户&#xff0c;设置用户名称&#xff0c;添加描述&a…

立体匹配算法(Stereo correspondence)SGM

SGM(Semi-Global Matching)原理&#xff1a; SGM的原理在wiki百科和matlab官网上有比较详细的解释&#xff1a; wiki matlab 如果想完全了解原理还是建议看原论文 paper&#xff08;我就不看了&#xff0c;懒癌犯了。&#xff09; 优质论文解读和代码实现 一位大神自己用c实现…

IntelliJ IDEA [插件 MybatisX] mapper和xml间跳转

文章目录 1. 安装插件2. 如何使用3. 主要功能总结 MybatisX 是一款为 IntelliJ IDEA 提供支持的 MyBatis 开发插件 它通过提供丰富的功能集&#xff0c;大大简化了 MyBatis XML 文件的编写、映射关系的可视化查看以及 SQL 语句的调试等操作。本文将介绍如何安装、配置和使用 In…

redis 三主六从高可用docker(不固定ip)

redis集群(cluster)笔记 redis 三主三从高可用集群docker swarm redis 三主六从高可用docker(不固定ip) 此博客解决&#xff0c;redis加入集群后&#xff0c;是用于停掉后重启&#xff0c;将nodes.conf中的旧的Ip替换为新的IP&#xff0c;从而达到不会因为IP变化导致集群无法…

StackOverflowError的JVM处理方式

背景&#xff1a; 事情来源于生产的一个异常日志 Caused by: java.lang.StackOverflowError: null at java.util.stream.Collectors.lambda$groupingBy$45(Collectors.java:908) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.ArrayL…

阿里云 ACK 云上大规模 Kubernetes 集群高可靠性保障实战

作者&#xff1a;贤维 马建波 古九 五花 刘佳旭 引言 2023 年 7 月&#xff0c;阿里云容器服务 ACK 成为首批通过中国信通院“云服务稳定运行能力-容器集群稳定性”评估的产品&#xff0c; 并荣获“先进级”认证。随着 ACK 在生产环境中的采用率越来越高&#xff0c;稳定性保…

【ES6】Class继承-super关键字

目录 一、前言二、ES6与ES5继承机制区别三、super作为函数1、构造函数this1&#xff09;、首先要明确this指向①、普通函数②、箭头函数③、注意事项 2&#xff09;、其次要明确new操作符做了哪些事情 2、super()的用法及注意点1&#xff09;、用法2&#xff09;、注意点 四、s…

Unity引擎有哪些优点

Unity引擎是一款跨平台的游戏引擎&#xff0c;拥有很多的优点&#xff0c;如跨平台支持、强大的工具和编辑器、灵活的脚本支持、丰富的资源库和强大的社区生态系统等&#xff0c;让他成为众多开发者选择的游戏开发引擎。下面我简单的介绍一下Unity引擎的优点。 跨平台支持 跨…

用Xshell连接虚拟机的Ubuntu20.04系统记录。虚拟机Ubuntu无法上网。本机能ping通虚拟机,反之不能。互ping不通

先别急着操作&#xff0c;看完再试。 如果是&#xff1a;本机能ping通虚拟机&#xff0c;反之不能。慢慢看到第8条。 如果是&#xff1a;虚拟机不能上网&#xff08;互ping不通&#xff09;&#xff0c;往下一直看。 系统是刚装的&#xff0c;安装步骤&#xff1a;VMware虚拟机…

TCP 滑动窗口

滑动窗口&#xff08;Sliding window&#xff09;是一种流量控制技术。早期的网络通信中&#xff0c;通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况&#xff0c;同时发送数据&#xff0c;导致中间节点阻塞掉包&#xff0c;谁也发不了数据&#xff0…

数据分析工具 Top 8

你能想象一个没有工具箱的水管工吗? 没有,对吧? 数据从业者也是如此。如果没有他们的数据分析工具&#xff0c;数据从业者就无法分析数据、可视化数据、从数据中提取价值&#xff0c;也无法做数据从业者在日常工作中做的许多很酷的事情。 根据你最感兴趣的数据科学职业——数…

VR与数字孪生:共同构筑未来的虚拟世界

随着科技的不断发展&#xff0c;数字孪生和VR已经成为当今热门的科技话题。作为山海鲸可视化软件的开发者&#xff0c;我们对这两者都有深入的了解。在此&#xff0c;我们将详细探讨数字孪生与VR的区别和联系。 首先&#xff0c;数字孪生&#xff08;Digital Twin&#xff09;…

深度学习 | DRNN、BRNN、LSTM、GRU

1、深度循环神经网络 1.1、基本思想 能捕捉数据中更复杂模式并更好地处理长期依赖关系。 深度分层模型比浅层模型更有效率。 Deep RNN比传统RNN表征能力更强。 那么该如何引入深层结构呢&#xff1f; 传统的RNN在每个时间步的迭代都可以分为三个部分&#xff1a; 1.2、三种深层…

pymol--常用指令

1. 导入蛋白质 1&#xff09;Pymol> load name.pdb, name # 载入pdb文件&#xff0c;并命名&#xff0c;我还没试过 Pymol> fetch proteinID # 直接就加载了 我用的这个 右边选框&#xff0c;有A S H L C指令 2. 保存图片 2.1 直接输出PNG&#xff0c;在pymol后输…

k8s的网络类型

部署 CNI 网络组件 部署 flannel K8S 中 Pod 网络通信&#xff1a; ●Pod 内容器与容器之间的通信 在同一个 Pod 内的容器&#xff08;Pod 内的容器是不会跨宿主机的&#xff09;共享同一个网络命名空间&#xff0c; 相当于它们在同一台机器上一样&#xff0c;可以用 localho…
最新文章