掌握高级设计原则:Java中的过滤器模式解析与实战演练,构建灵活且可扩展的系统架构

news2024/11/20 2:29:40

过滤器模式是一种结构型设计模式,它允许开发者使用不同的标准来过滤一组对象,并通过逻辑运算以解耦的方式将它们联系起来。

过滤器模式的核心在于提供了一个处理对象的机制,这个机制可以根据一个或多个标准来决定哪些对象应该被接受、哪些应该被排除。这种模式通常用于实现复杂的数据筛选和处理逻辑,尤其是在需要将数据处理过程分解为多个独立步骤时。以下是过滤器模式的一些关键点:

  1. 角色定义:在过滤器模式中,通常会有一个抽象过滤器角色(AbstractFilter),它负责定义过滤器的实现接口。具体的实现则由具体过滤器角色(Concrete Filter)来完成,它们实现了抽象过滤器定义的接口,并提供具体的过滤逻辑。
  2. 链式结构:过滤器模式通常以链式结构来实现,这意味着一个过滤器处理完数据后,可以将处理结果传递给下一个过滤器。这种链式结构使得每个过滤器都只需要关注自己的职责,而不必知道其他过滤器的具体实现。
  3. 应用场景:过滤器模式适用于需要对数据进行多步骤处理的情况,例如网络请求的处理、数据库查询的结果筛选等。通过使用过滤器模式,可以灵活地添加或移除处理步骤,而不影响其他部分的代码。
    一个简单的过滤器模式如图所示:
    在这里插入图片描述

过滤器模式允许动态地组合多个过滤条件,以便从一组对象中选择出满足特定标准的对象集合。通过将不同的过滤器加入到 AndCriteria 中,可以灵活地控制筛选结果。

代码示例

下面是一个简单的Java过滤器模式实现的例子,我们定义了Person类、Criteria接口以及两个具体的过滤器:AgeCriteria和NameCriteria,还有一个复合过滤器AndCriteria,它允许我们将多个过滤器逻辑串联起来使用。在主函数中,我们创建了一个人员列表并对之应用了复合过滤条件来获取特定年龄段且名字包含特定字符串的人。:
定义一个Person实体类:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 省略getter和setter方法
}

定义过滤器接口:

public interface Criteria {
    public List<Person> meetCriteria(List<Person> persons);
}

实现年龄过滤器:

public class AgeCriteria implements Criteria {
    private int minAge;
    private int maxAge;

    public AgeCriteria(int minAge, int maxAge) {
        this.minAge = minAge;
        this.maxAge = maxAge;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> filteredPersons = new ArrayList<>();
        for (Person person : persons) {
            if (person.getAge() >= minAge && person.getAge() <= maxAge) {
                filteredPersons.add(person);
            }
        }
        return filteredPersons;
    }
}

实现名称过滤器:

// 实现名称过滤器
public class NameCriteria implements Criteria {
    private String nameSubstring;

    public NameCriteria(String nameSubstring) {
        this.nameSubstring = nameSubstring;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> filteredPersons = new ArrayList<>();
        for (Person person : persons) {
            if (person.getName().contains(nameSubstring)) {
                filteredPersons.add(person);
            }
        }
        return filteredPersons;
    }
}

定义组合过滤器,可以添加多个Criteria进行复合过滤:

public class AndCriteria implements Criteria {
    private Criteria criteria1;
    private Criteria criteria2;

    public AndCriteria(Criteria criteria1, Criteria criteria2) {
        this.criteria1 = criteria1;
        this.criteria2 = criteria2;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> intermediateResult = criteria1.meetCriteria(persons);
        return criteria2.meetCriteria(intermediateResult);
    }
}

使用示例:

public class FilterPatternDemo {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 25),
            new Person("Bob", 30),
            new Person("Charlie", 35),
            new Person("David", 40)
        );

        Criteria ageCriteria = new AgeCriteria(28, 36);
        Criteria nameCriteria = new NameCriteria("arlie"); // 包含"arlie"的名字

        Criteria combinedCriteria = new AndCriteria(ageCriteria, nameCriteria);

        List<Person> filteredPeople = combinedCriteria.meetCriteria(people);
        for (Person person : filteredPeople) {
            System.out.println(person.getName());
        }
    }
}

过滤器模式的优点

  1. 提高代码的灵活性和可维护性:过滤器模式通过提供一个灵活的处理和筛选对象集合的方法,使得在不改变代码结构的前提下,可以很方便地增加新的过滤标准或者修改现有的过滤逻辑。
  2. 高内聚低耦合:该模式允许多个过滤器以松耦合的方式组合在一起,每个过滤器负责一个具体的过滤条件,这样可以独立地改变和复用各个过滤器。
  3. 多过滤器简单合成:多个过滤器可以简单地合成一个新的过滤器,从而实现更复杂的过滤逻辑。
  4. 功能模块重用:由于每个过滤器都是独立的,它们可以在其他场景中被重用,这提高了系统的模块性。

过滤器模式的缺点

  1. 性能下降:由于每个过滤器都需要对每个元素进行处理,如果有多个元素和多个过滤器,这将导致性能问题,复杂度为O(mn),其中n是元素数量,m是过滤器数量。
  2. 实现复杂:在实现过滤器模式时,可能需要处理一些复杂的逻辑,以确保过滤器之间能够正确地协同工作。
  3. 需协调数据流:在多个过滤器之间传递数据可能会使数据流的控制变得更加复杂。

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

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

相关文章

代码学习记录21--回溯算法第二天

随想录日记part21 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.16 主要内容&#xff1a;今天主要是结合类型的题目加深对回溯算法的理解&#xff1a;1&#xff1a;组合总和&#xff1b;2&#xff1a;电话号码的字母组合 216.组合总和III17.电话号码的字母…

快速了解微软推出的开发人员主页的应用

一、概述 开发人员主页是微软推出的一个新的 Windows 控制中心&#xff0c;提供以下功能&#xff1a;使用可自定义小组件监视仪表板中的项目&#xff0c;通过下载应用、包或存储库来设置开发环境&#xff0c;连接到开发人员帐户和工具&#xff08;如 GitHub&#xff09;&#x…

【C++进阶】深度解析AVL树及其简单模拟实现

AVL树的解析和模拟实现 一&#xff0c;什么是AVL树二&#xff0c;AVL树的特性三&#xff0c;模拟实现1. 基本框架2. 插入&#xff08;不带旋转&#xff09;2. AVL树的旋转3. AVL树的验证 四&#xff0c;总结 一&#xff0c;什么是AVL树 之前我们学习了二叉搜索树&#xff0c;但…

【每日力扣】40.组合总和II与701. 二叉搜索树中的插入操作

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 40.组合总和II 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为…

【小白学机器学习8】统计里的自由度DF=degree of freedom, 以及关于df=n-k, df=n-k-1, df=n-1 等自由度公式

目录 1 自由度 /degree of freedom / df 1.1 物理学的自由度 1.2 数学里的自由度 1.2.1 数学里的自由度 1.2.2 用线性代数来理解自由度&#xff08;需要补充&#xff09; 1.2.3 统计里的自由度 1.3 统计学里自由度的定义 2 不同对象的自由度 2.1 纯公式的自由度&#…

报Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String错误

在springboot中使用Mybatis出现Invalid value type for attribute factoryBeanObjectType: java.lang.String 1、没有使用mybatis 检查pom文件里面的mybatis 可能是缺少这个依赖&#xff0c;或者版本过低 重新导入依赖 <dependency><groupId>org.mybatis.spri…

华为数通方向HCIP-DataCom H12-821题库(多选题:141-160)

第141题 以下关于802.1X认证的触发机制,描述正确的有? A、802.1X认证不能由认证设备(如802.1交换机)发起 B、802.1X客户端可以组播或广播方式触发认证 C、认证设备可以以组播或单播方式触发认证 D、802.1X认证只能由客户端主动发起 【参考答案】BC 【答案解析】 第142题 以…

集合系列(二) -List接口详解

一、List简介 List 的数据结构就是一个序列&#xff0c;存储内容时直接在内存中开辟一块连续的空间&#xff0c;然后将空间地址与索引对应。 以下是List集合简易架构图 由图中的继承关系&#xff0c;可以知道&#xff0c;ArrayList、LinkedList、Vector、Stack都是List的四个…

B3620 x 进制转 10 进制(详解)

题目 思路 八进制数567怎么转化为十进制数。首先八进制就是逢八进一&#xff0c;也就是说这里面最大的数也就7&#xff0c;没有≥8的数。下面我们就讲一下567怎么转化为十进制&#xff1a;首先7是个位&#xff0c;可以直接写成十进制的7&#xff0c;6是十位&#xff0c;它是通…

springboot基于java的畅销图书推荐系统

摘 要 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一…

AI_寻路系统_修改寻路网格体

学习笔记&#xff0c;仅供参考&#xff01; 一、完成创建关卡和AI代理的初步步骤&#xff0c;以演示可以修改导航系统的不同方法。 创建简单关卡&#xff0c;并通过在关卡中放入导航网格体边界体积Actor来添加导航。 将ThirdPersonCharacter蓝图修改为使用导航系统在关卡中四…

vuepress-theme-vdoing博客搭建教程

搭建流程 前言 这是笔者搭建个人博客所经历的流程&#xff0c;特附上笔记 笔者个人博客地址&#xff1a;沉梦听雨的编程指南 一、主题介绍 本博客使用的主题为&#xff1a;vuepress-theme-vdoing&#xff0c;相关介绍和使用方法可以参考该主题的官方文档 官方文档快速上手…

力扣趣味题:找不同

经典面向样例编程 char findTheDifference(char* s, char* t) {if(sNULL){return t[0];}for(int x0;x<strlen(s);x){for(int y0;y<strlen(t);y){if(s[x]t[y]){t[y]1;break;}}}for(int x0;x<strlen(t);x){if(t[x]!1){return t[x];}}return NULL; }

银发经济@315:消费、陷阱与孤独的老人

【潮汐商业评论/文】 又是一年315。 这一天&#xff0c;从品牌到消费者&#xff0c;从线下到网络&#xff0c;都不约而同地将目光锁定在大众消费生活和与其相伴的消费“陷阱”上。 这其中&#xff0c;作为“有闲又有钱”且与社会经济发展速度相对有一定“代沟”的老年消费者群…

新加坡大带宽服务器托管优势

在数字化快速发展的今天&#xff0c;服务器托管成为企业拓展业务、提高服务质量的关键环节。而新加坡作为一个国际性的金融、贸易和科技创新中心&#xff0c;其大带宽服务器托管服务在全球范围内享有盛誉。本文将为您科普新加坡大带宽服务器托管的诸多优势。 首先&#xff0c;新…

AXI CANFD MicroBlaze 测试笔记

文章目录 前言测试用的硬件连接Vivado 配置Vitis MicroBlaze CANFD 代码测试代码测试截图Github Link 前言 官网: CAN with Flexible Data Rate (CAN FD) (xilinx.com) 特征: 支持8Mb/s的CANFD多达 3 个数据位发送器延迟补偿(TDC, transmitter delay compensation)32-deep T…

VS Code上,QT基于cmake,qmake的构建方法(非常详细)

VS Code上,QT基于cmake&#xff0c;qmake的构建方法 1 前言2 QT基于cmake的构建方法2.1 VS Code关键插件安装2.2 系统环境变量配置2.3 VS Code中&#xff0c;环境变量配置2.4 Cmake新建一个新的Porject 3 QT基于qmake的构建方法 1 前言 最近&#xff0c;由于认证了github的学生…

RabbitMQ学习总结-延迟消息

1.死信交换机 一致不被消费的信息/过期的信息/被标记nack/reject的信息&#xff0c;这些消息都可以进入死信交换机&#xff0c;但是首先要配置的有私信交换机。私信交换机可以再RabbitMQ的客户端上选定配置-dead-letter-exchange。 2.延迟消息 像我们买车票&#xff0c;外卖…

PHP 生成图片

1.先确认是否有GD库 echo phpinfo(); // 创建一个真彩色图像 $image imagecreatetruecolor(120, 50);// 分配颜色 $bgColor imagecolorallocate($image, 255, 255, 255); // 白色背景 $textColor imagecolorallocate($image, 230, 230, 230); // 黑色文字// 填充背景 image…

MyFileServer

靶场下载地址 https://download.vulnhub.com/myfileserver/My_file_server_1.ova 信息收集 # nmap -sn 192.168.56.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-24 22:07 CST Nmap scan report for 192.168.56.2 (192.168.56.2) Host is up (0.…