行业知识
Java特性之设计模式【过滤器模式】
2026-11-11 03:46:26
来源:互联网转载
一、过滤器模式
���述
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准
主要解决:在众多数据中,根据特定的标准,在一组数据中筛选出不同标准的数据
优缺点
优点:
- 将对象的过滤、校验逻辑抽离出来,降低系统的复杂度
- 过滤规则可实现重复利用
缺点:
- 性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则时间复杂度为O(mn)
1. 各个角色介绍
1.1 过滤器接口(Filter)
- 定义了过滤器的基本方法,具体的实现还要具体过滤器角色去参与,在实际应用中可以扩展该接口以适应不同的过滤条件
1.2 具体命过滤器(ConcreteFilter)
- 实现了过滤器接口,负责执行具体的过滤操作。对数据进行过滤
1.3 过滤链(FilterChain)
-
将多个过滤器按照一定的顺序组合起来,形成一个过滤器链,依次对数据进行过滤
2. UML图
首先创建一个 Shape 对象,作为过滤的接口 IFilter,然后实现该接口,创建对应的 CornerFilter、CurveFilter、EdgeFilter具体过滤器。然后创建带有过滤器的过滤链 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 adaptFilter(List 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 adaptFilter(List shapes) { // 符合具有角的形状 List 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 adaptFilter(List shapes) { // 边数大于0的形状 List 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 adaptFilter(List shapes) { // 曲线 List 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 过滤链 */@Datapublic class FilterChain { @ApiModelProperty("过滤器集合") private List filters; public FilterChain(List filters) { this.filters = filters; } public List doFilter(List shapes) { if (CollectionUtils.isEmpty(filters) || CollectionUtils.isEmpty(shapes)) { return new ArrayList(); } List 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 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 cornerAndEdgeShapes = cornerAndEdgeFilterChain.doFilter(shapes); System.out.println("具有角、边的形状:"); printResult(cornerAndEdgeShapes); // 具有角、曲线的形状 FilterChain cornerAndCurveFilterChain = new FilterChain(Arrays.asList(cornerFilter, curveFilter)); List cornerAndCurveShapes = cornerAndCurveFilterChain.doFilter(shapes); System.out.println("\n具有角、曲线的形状:"); printResult(cornerAndCurveShapes); // 具有边、曲线的形状 FilterChain edgeAndCurveFilterChain = new FilterChain(Arrays.asList(edgeFilter, curveFilter)); List edgeAndCurveShapes = edgeAndCurveFilterChain.doFilter(shapes); System.out.println("\n具有边、曲线的形状:"); printResult(edgeAndCurveShapes); } public static void printResult(List shapes) { for (Shape shape : shapes) { System.out.println("Shape{" + "name='" + shape.getName() + '\'' + ", isCorner=" + shape.getIsCorner() + ", edges=" + shape.getEdges() + ", type='" + shape.getType() + '\'' + '}'); } }}- 测试结果
4. 使用场景
- 在某些场合,比如要对数据进行过滤,不仅仅局限于一个标准的情况下,进行分组,例如:数据查询、日志过滤、请求过滤
- 测试结果
- FilterChain
- CurveFilter
- EdgeFilter
- CornerFilter
- IFilter
- Instruction
-
- 实现了过滤器接口,负责执行具体的过滤操作。对数据进行过滤
- 定义了过滤器的基本方法,具体的实现还要具体过滤器角色去参与,在实际应用中可以扩展该接口以适应不同的过滤条件
- 性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则时间复杂度为O(mn)
上一篇:服务器双网卡怎么绑定?