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

news2024/10/24 14:25:34

一、过滤器模式

概述

​ 过滤器模式(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 {

    @Override
    public 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 {

    @Override
    public 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 {

    @Override
    public 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.coloradmin.cn/o/1497905.html

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

相关文章

几何工具的使用

Geometry - Creation 创建几何 CogCreateCircleTool&#xff1a;创建圆CogCreateEllipseTool:创建椭圆CogCreateLineBisectPointsTool&#xff1a;带有两个点的平行线CogCreateLineParallelTool:在某一点创建某条线的平行线CogCreateLinePerpendicularTool:在某一点创建某条线…

STL中push_back和emplace_back效率的对比

文章目录 过程对比1.通过构造参数向vector中插入对象&#xff08;emplace_back更高效&#xff09;2.通过插入实例对象&#xff08;调用copy函数&#xff09;3.通过插入临时对象&#xff08;调用move函数&#xff09; 效率对比emplace_back 的缺点 我们以STL中的vector容器为例。…

力扣每日一题 找出字符串的可整除数组 数论

Problem: 2575. 找出字符串的可整除数组 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 灵神题解 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code class Solution {public int[] divisibilityArray(String word, int m){in…

外包干了一周,技术明显倒退。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

【JavaEE初阶】 JVM 运行时数据区简介

文章目录 &#x1f343;前言&#x1f332;堆&#xff08;线程共享&#xff09;&#x1f384;Java虚拟机栈&#xff08;线程私有&#xff09;&#x1f38b;本地方法栈&#xff08;线程私有&#xff09;&#x1f333;程序计数器&#xff08;线程私有&#xff09;&#x1f334;方法…

ospf虚链路实验简述

1、ospf虚链路实验简述 ospf虚链路配置 为解决普通区域不在骨干区域旁&#xff0c;通过配置Vlink-peer实现不同区域网络设备之间建立逻辑上的连接。 实验拓扑图 r1: sys sysname r1 undo info enable int loopb 0 ip add 1.1.1.1 32 ip add 200.200.200.200 32 quit int e0/0/…

京东老矣,尚能饭否?

图片&#xff5c;《冰与火之歌》截图 ©自象限原创 作者丨程心 编辑丨罗辑 从2004年1月&#xff0c;京东正式涉足电商至今&#xff0c;整整二十年过去了。 2024年3月6日&#xff0c;京东发布了2023年第四季度及全年财报。数据显示&#xff0c;2023Q4京东收入3061亿元人民…

【软件测试】如何申请专利?

一、专利类型 在软件测试领域&#xff0c;可以申请发明专利、实用新型专利和外观设计专利。其中&#xff0c;发明专利是最常见的专利类型&#xff0c;它保护的是软件测试方法、系统和装置等技术方案。 二、申请专利的条件 申请专利需要满足新颖性、创造性和实用性三个条件。…

【Linux】开始使用gdb吧!

开始使用gdb吧&#xff01; 1 下载安装2 开始使用3 实践运用补充一下 print 的 功能 &#xff08;类似监视窗口的作用&#xff09;和显示堆栈的功能Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff01;&am…

【力扣白嫖日记】1070.产品销售分析III

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1070.产品销售分析III 表&#xff1a;Sales 列名类型sale_idintproduct_idintyearintquantityintpriceint …

01背包问题 刷题笔记

思路 dp 用f[i][j]来表示当体积为j时 考虑前i件物品可以获得的 最大值 记住f[i][j]本身是个价“价值” 考虑两种状态 是否将第i件物品放入背包里面 将背包的体积从小到大递增来进行考虑 首先 考虑条件 如果当前增加的体积放不下下一件物品 则该体积 可以获得的最大值可以直接…

Easticsearch性能优化之索引优化

Easticsearch性能优化之索引优化 一、合理的索引设计二、合理的分片和副本三、合理的索引设置 对于性能优化&#xff0c;Elasticsearch&#xff08;以下简称ES&#xff09;的索引优化是提高性能的关键因素之一。合理的设计索引&#xff0c;合理的分片和副本以及合理的缓存设置等…

Truenas入门级教程

Truenas入门教程 前言&#xff1a;系统相关配置 采用I3 4160&#xff0c;采用了2块500G的硬盘&#xff0c;内存为8G&#xff0c;两个网卡只用了其中一个&#xff0c;系统安装的是core版本 硬件采用DELL3020MT机箱&#xff0c;自带3个SATA网口&#xff0c;后期网口不够&#…

七.AV Foundation 视频播放 - 图片进度条

引言 播放器的功能功能已经十分完善了&#xff0c;接下来我们给它添加一些提升用户体验的功能。当前市面上的主流播放器几乎都有一个非常友善的功能&#xff0c;用户在退拽进度条的时候可以看见进度条所处进度的视频画面&#xff0c;这对于用户来说是一种直观而且便捷的体验。…

今天分享一个好看的输入法皮肤相信每个人心里住着一个少女心我们美化一下她吧

标题&#xff1a; 白日梦皮肤上线&#xff0c;百度输入法助你开启梦幻之旅&#xff01; 正文&#xff1a; 大家好呀&#xff01;今天我来给大家安利一款超级梦幻的百度输入法皮肤——“白日梦”系列&#xff01; 这款皮肤的设计灵感来源于我们内心深处的白日梦&#xff0c;充…

【Python】新手入门(9):数值和序列

&#x1f40d;【Python】新手入门&#xff08;9&#xff09;&#xff1a;数值和序列 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&am…

MySQL为什么要用B+树?

二叉树&#xff08;二叉查找树&#xff09; 平衡二叉树&#xff08;B树就是B-树&#xff09;(解决了二叉查找树的极端情况&#xff09; Q&#xff1a;具体是怎么解决的呢&#xff1f; A&#xff1a; 树左右两边层数相差不大于1一旦符合条件1的时候&#xff0c;就进行左旋/右…

重装系统后正版office如何安装

前言 重装系统后&#xff0c;正版office如何安装 登录官网 https://www.microsoft.com 下载office https://account.microsoft.com/services

KOA优化最近邻分类预测(matlab代码)

KOA-最近邻分类预测matlab代码 开普勒优化算法&#xff08;Kepler Optimization Algorithm&#xff0c;KOA&#xff09;是一种元启发式算法&#xff0c;灵感来源于开普勒的行星运动规律。该算法模拟行星在不同时间的位置和速度&#xff0c;每个行星代表一个候选解&#xff0c;…

STM32标准库——(19)PWR电源控制

1.PWR简介 PWR属于外设部分 调用时需要先开启时钟 2.电源框图 这个图可以分为三个部分&#xff0c;最上面是模拟部分供电叫做VDDA&#xff0c;中间是数字部分供电&#xff0c;包括两块区域&#xff0c;VDD供电区域和1.8v供电区域&#xff0c;下面是后备供电&#xff0c;叫做VB…