Java特性之设计模式【过滤器模式】

一、过滤器模式

概述

​ 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准

主要解决:在众多数据中,根据特定的标准,在一组数据中筛选出不同标准的数据

优缺点

优点:

  • 将对象的过滤、校验逻辑抽离出来,降低系统的复杂度
  • 过滤规则可实现重复利用

缺点:

  • 性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则时间复杂度为O(mn)

1. 各个角色介绍

1.1 过滤器接口(Filter)

  • 定义了过滤器的基本方法,具体的实现还要具体过滤器角色去参与,在实际应用中可以扩展该接口以适应不同的过滤条件

1.2 具体命过滤器(ConcreteFilter)

  • 实现了过滤器接口,负责执行具体的过滤操作。对数据进行过滤

1.3 过滤链(FilterChain)

  • 将多个过滤器按照一定的顺序组合起来,形成一个过滤器链,依次对数据进行过滤

2. UML图

​ 首先创建一个 Shape 对象,作为过滤的接口 IFilter,然后实现该接口,创建对应的 CornerFilterCurveFilterEdgeFilter具体过滤器。然后创建带有过滤器的过滤链 FilterChain,基于各种标准和它们的结合来过滤 Shape 对象的列表

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状
  • IFilter:过滤器接口
    • CornerFilter:角过滤器(实现过滤器接口)
    • EdgeFilter:边过滤器(实现过滤器接口)
    • CurveFilter:曲线过滤器(实现过滤器接口)
  • FilterChain:过滤链

3.1 形状

  • Instruction
package com.vinjcent.prototype.filter;import io.swagger.annotations.ApiModelProperty;/*** @author vinjcent* @description 形状*/
public class Shape {@ApiModelProperty("形状名称")private String name;@ApiModelProperty("是否有角")private Boolean isCorner;@ApiModelProperty("边数")private Integer edges;@ApiModelProperty("线构成类型")private String type;public Shape(String name, Boolean isCorner, Integer edges, String type) {this.name = name;this.isCorner = isCorner;this.edges = edges;this.type = type;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Boolean getCorner() {return isCorner;}public void setCorner(Boolean corner) {isCorner = corner;}public Integer getEdges() {return edges;}public void setEdges(Integer edges) {this.edges = edges;}public String getType() {return type;}public void setType(String type) {this.type = type;}
}

3.2 过滤接口及其实现类

  • IFilter
package com.vinjcent.prototype.filter;import java.util.List;/*** @author vinjcent* @description 过滤接口*/
public interface IFilter {/*** 适配标准形状** @param shapes 形状列表* @return 适配的形状列表*/List<Shape> adaptFilter(List<Shape> shapes);
}
  • CornerFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 角过滤器*/
public class CornerFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 符合具有角的形状List<Shape> cornerFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getIsCorner()) {cornerFilter.add(shape);}}return cornerFilter;}}
  • EdgeFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 边过滤器*/
public class EdgeFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 边数大于0的形状List<Shape> edgeFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getEdges() > 0) {edgeFilter.add(shape);}}return edgeFilter;}}
  • CurveFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 曲线过滤器*/
public class CurveFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 曲线List<Shape> curveFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getType().toLowerCase().contains("curve")) {curveFilter.add(shape);}}return curveFilter;}}

3.3 过滤链

  • FilterChain
package com.vinjcent.prototype.filter;import com.vinjcent.api.utils.CollectionUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* @description 过滤链*/
@Data
public class FilterChain {@ApiModelProperty("过滤器集合")private List<IFilter> filters;public FilterChain(List<IFilter> filters) {this.filters = filters;}public List<Shape> doFilter(List<Shape> shapes) {if (CollectionUtils.isEmpty(filters) || CollectionUtils.isEmpty(shapes)) {return new ArrayList<>();}List<Shape> afterFilterShapes = new ArrayList<>(shapes);// 执行过滤for (IFilter filter : filters) {afterFilterShapes = filter.adaptFilter(afterFilterShapes);}return afterFilterShapes;}
}

3.4 测试主函数

package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @author vinjcent* 过滤模式*/
public class Main {public static void main(String[] args) {List<Shape> shapes = new ArrayList<>();shapes.add(new Shape("Circle", false, 0, "Curve"));shapes.add(new Shape("Triangle", true, 3, "Straight"));shapes.add(new Shape("Rectangle", true, 4, "Straight"));shapes.add(new Shape("Square", true, 4, "Straight"));shapes.add(new Shape("Oval", false, 0, "Curve"));shapes.add(new Shape("Sector", true, 2, "Curve and Straight"));CornerFilter cornerFilter = new CornerFilter();EdgeFilter edgeFilter = new EdgeFilter();CurveFilter curveFilter = new CurveFilter();// 具有角、边的形状FilterChain cornerAndEdgeFilterChain = new FilterChain(Arrays.asList(cornerFilter, edgeFilter));List<Shape> cornerAndEdgeShapes = cornerAndEdgeFilterChain.doFilter(shapes);System.out.println("具有角、边的形状:");printResult(cornerAndEdgeShapes);// 具有角、曲线的形状FilterChain cornerAndCurveFilterChain = new FilterChain(Arrays.asList(cornerFilter, curveFilter));List<Shape> cornerAndCurveShapes = cornerAndCurveFilterChain.doFilter(shapes);System.out.println("\n具有角、曲线的形状:");printResult(cornerAndCurveShapes);// 具有边、曲线的形状FilterChain edgeAndCurveFilterChain = new FilterChain(Arrays.asList(edgeFilter, curveFilter));List<Shape> edgeAndCurveShapes = edgeAndCurveFilterChain.doFilter(shapes);System.out.println("\n具有边、曲线的形状:");printResult(edgeAndCurveShapes);}public static void printResult(List<Shape> shapes) {for (Shape shape : shapes) {System.out.println("Shape{" +"name='" + shape.getName() + '\'' +", isCorner=" + shape.getIsCorner() +", edges=" + shape.getEdges() +", type='" + shape.getType() + '\'' +'}');}}}
  • 测试结果

在这里插入图片描述

4. 使用场景

  • 在某些场合,比如要对数据进行过滤,不仅仅局限于一个标准的情况下,进行分组,例如:数据查询、日志过滤、请求过滤

在这里插入图片描述

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

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

相关文章

OpenStack之Nova

一 、Nova 使用OpenStack Compute来托管和管理云计算系统。 OpenStack Compute是基础架构即服务 &#xff08;IaaS&#xff09;系统的主要部分。 主要模块在Python中实现&#xff1a; 1因为认证&#xff0c;与OpenStack 身份认证keystone 交互。 2因为磁盘和服务器镜像&#xf…

【Maven】Maven 基础教程(五): jar 包冲突问题

《Maven 基础教程》系列&#xff0c;包含以下 5 篇文章&#xff1a; Maven 基础教程&#xff08;一&#xff09;&#xff1a;基础介绍、开发环境配置Maven 基础教程&#xff08;二&#xff09;&#xff1a;Maven 的使用Maven 基础教程&#xff08;三&#xff09;&#xff1a;b…

C++ · 代码笔记3 · 引用

目录 前言011引用初探_引用与普通变量012引用初探_引用作为函数参数013引用初探_引用作为函数返回值014引用初探_引用返回局部函数造成的错误015引用初探_多级引用020引用与指针递增的区别030const与引用040使用const限定的函数形参引用 前言 本笔记所涉及到的编程环境与 《C …

经典语义分割(二)医学图像分割模型UNet

经典语义分割(二)医学图像分割模型UNet 我们之前介绍了全卷积神经网络( FCN) &#xff0c;FCN是基于深度学习的语义分割算法的开山之作。 今天我们介绍另一个语义分割的经典模型—UNet&#xff0c;它兼具轻量化与高性能&#xff0c;通常作为语义分割任务的基线测试模型&#x…

opengl 学习(三)-----着色器

着色器 分类demo效果解析教程 分类 OPengl C demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>#include <string> #include <fstream> #include <sstream>…

苍穹外卖技术栈

Day5 Redis_Spring Data Redis使用方法 Spring Data Redis Spring Date Redis 是Spring的一部分&#xff0c; 对Redis底层开发包进行了高度封装&#xff0c;在Spring项目中&#xff0c;可以使用Spring Data Redis来简化操作。 操作步骤 导入Spring Data Redis 的maven坐标配置…

浮点数和定点数

前言 大家好我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第七篇,在这里分享给大家,还有一些书籍《深入理解计算机系统》《计算机组成&#xff1a;结构化方法》《计算机体系结构&#xff1a;量化研究方法》&#xff0c;今天我们来了解定点数和浮点数 定点数 BCD编码 …

JavaScript基础4之原型的原型继承、原型链和理解对象的数据属性、访问器属性

JavaScript基础 原型原型继承问题解决 原型链isPrototypeOf()Object.getPrototypeOf() 理解对象数据属性访问器属性 原型 原型继承 继承是面向对象编程的另一个特征&#xff0c;通过继承进一步提升代码封装的程度&#xff0c;JavaScript中大多是借助原型对象实现继承的特性。…

蜘蛛池是什么意思,怎么生成蜘蛛池

蜘蛛池是由自然界中的蜘蛛群落构成的一个小生态系统&#xff0c;也是身处自然界中的游客们可以在风雨中体验到最贴近自然气息的地方。 点开我主页面 Baidu蜘蛛的作用&#xff1a; 引蜘蛛逐渐收录&#xff0c;降权引蜘蛛可以疗伤&#xff0c;排名/收录不稳定&#xff0c;没有收…

【Linux篇】gdb的使用

&#x1f49b;不要有太大压力&#x1f9e1; &#x1f49b;生活不是选择而是热爱&#x1f9e1; &#x1f49a;文章目录&#x1f49a; 1. 背景知识2. 使用 1. 背景知识 1. 程序发布的方式有两种&#xff0c;debug模式和release模式 2. Linux下&#xff0c;gcc和g编译生成的可执行…

国家积极推进长城国家文化公园建设

长城脚下&#xff0c;文化绽放——国家积极推进长城国家文化公园建设 在中华大地的北方&#xff0c;横亘着一条巨龙&#xff0c;它见证着中华民族的沧桑岁月&#xff0c;承载着我们的民族记忆&#xff0c;它就是——长城。这座千年的雄关&#xff0c;不仅是中国的象征&#xf…

[Unity实战]使用NavMeshAgent做玩家移动

其实除了Character Controller, Rigidbody&#xff0c;我们还可以使用NavMeshAgent去做。这么做的好处是能避免玩家去莫名其妙的地方&#xff08;毕竟基于烘焙过的导航网格&#xff09;&#xff0c;一般常见于元宇宙应用和mmo。 根据Unity手册&#xff0c;NavMeshAgent 也有和…

学c++对Python有帮助吗?

学习C对Python编程确实有帮助&#xff0c;尽管这两种语言在许多方面有很大的不同。以下是学习C可能对Python编程产生帮助的几个方面&#xff1a; 理解底层概念&#xff1a;C是一种更接近硬件的编程语言&#xff0c;它要求程序员更深入地理解内存管理、指针、数据类型等底层概念…

Linux:文件权限详解及修改方法

文章目录 1、Linux文件权限1.1、如何查看到文件权限1.2、ll命令介绍 2、权限分类2.1、文件权限2.2、文件夹权限 3、权限修改3.1、修改文件/文件夹权限1&#xff09;chmod指令2&#xff09;chmod指令符号 3.2、修改文件/文件夹所属用户3.3、修改文件/文件夹所属群组 4、参考 1、…

AI产品摄影丨香水

AI电商产品拍摄丨&#xff08;可指定产品&#xff09; 均为概念图 可换产品 可指定产品&#xff0c;可换logo 工具&#xff1a;StartAI 搭配“手机摄影”风格使用效果更佳哦 咒语&#xff1a;anha perfume in bottle on stone surface, in the style of everyday american…

和为K的子数组

题目&#xff1a; 使用前缀和的方法可以解决这个问题&#xff0c;因为我们需要找到和为k的连续子数组的个数。通过计算前缀和&#xff0c;我们可以将问题转化为求解两个前缀和之差等于k的情况。 假设数组的前缀和数组为prefixSum&#xff0c;其中prefixSum[i]表示从数组起始位…

分段线性化问题探析

目录 1 使用0-1变量将分段函数转换为线性约束 2 连续函数采用分段线性化示例 3 matlab程序测试 4 matlab测试结果说明 5 分段线性化应用 1 使用0-1变量将分段函数转换为线性约束 2 连续函数采用分段线性化示例 3 matlab程序测试 clc;clear all; gn10;tn1; x_pfsdpvar(1, t…

vue3基础教程(3)——引入ui框架iview(viewui)

博主个人微信小程序已经上线&#xff1a;【中二少年工具箱】。欢迎搜索试用 正文开始 专栏简介1. 下载iview2.更新资源3.引入插件4.运行项目 专栏简介 本系列文章由浅入深&#xff0c;从基础知识到实战开发&#xff0c;非常适合入门同学。 零基础读者也能成功由本系列文章入门…

底层day2作业

思维导图 作业&#xff1a; 1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度 连接硬件&#xff1a;将光敏电阻与单片机的ADC引脚连接&#xff0c;将LED灯与单片机的PWM引脚连接。初始化&#xff1a;在程序中初始化ADC和PWM模块&#xff0c;并设置相应的…

大数据分析技术工程师CCRC-BDATE

大数据分析技术工程师介绍 大数据始于科技之美&#xff0c;归于创造价值。大数据时代&#xff0c;“谁用好数据&#xff0c;谁就能把握先机、赢得主动”。当下数据驱动的电信、社交媒体、生物医疗、电子政务商务等行业都在产生着海量的数据&#xff0c;随着大规模数据关联、交叉…