过滤器模式、责任链模式

过滤器模式

意图:用于将对象的筛选过程封装起来,允许使用不同的筛选标准动态地筛选对象。

命令模式,是将"请求"封装为对象。而过滤器,是将"对象的筛选过程"封装。

比如spring security中的过滤链:

csharp 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterAfter(new LoggingFilter(), AuthorizationFilter.class);
        return http.build();
    }
}

写法:

csharp 复制代码
public class ADV {
    public static void main(String[] args) {
        AndFilter andFilter = new AndFilter(new MaleFilter(), new AdultFilter());
        andFilter.filter(xx);
    }
}
class User {

}
interface Filter {
    List<User> filter(List<User> users);
}

class MaleFilter  implements Filter {
    @Override
    public List<User> filter(List<User> users) {
        // 筛选女性
        return users.stream().filter()...;
    }
}


class AdultFilter  implements Filter {
    @Override
    public List<User> filter(List<User> users) {
        // 筛选成年
        return users.stream().filter()...;
    }
}
class AndFilter  implements Filter {
    Filter filter1;
    Filter filter2;
    public AndFilter(Filter filter1, Filter filter2) {
        this.filter1 = filter1;
        this.filter2 = filter2;
    }
    
    @Override
    public List<User> filter(List<User> users) {
        List<User> filter = filter1.filter(users);
        List<User> and = filter2.filter(users);
        return and;
    }
}

责任链模式

责任链模式通过将多个处理器(处理对象)以链式结构连接起来,使得请求沿着这条链传递,直到有一个处理器处理该请求为止。

意图:允许将请求沿着处理者链传递,直到请求被处理为止。。

主要解决的问题:解耦请求发送者和接收者,使多个对象都有可能接收请求,而发送者不需要知道哪个对象会处理它。(类似于观察者了)

代码示例:请假审批流程

以 "员工请假审批" 为例,请假天数不同,审批层级不同(班长:≤3 天;系主任:≤7 天;校长:≤30 天):

  1. 定义请求对象(请假单)
dart 复制代码
java
运行
// 请求:请假单
public class LeaveRequest {
    private String name;    // 申请人
    private int days;       // 请假天数

    public LeaveRequest(String name, int days) {
        this.name = name;
        this.days = days;
    }

    // getter
    public String getName() { return name; }
    public int getDays() { return days; }
}
  1. 定义抽象处理器(审批者)
dart 复制代码
java
运行
// 抽象处理器:审批者
public abstract class Approver {
    protected Approver nextApprover; // 下一个审批者(形成链)

    public Approver(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    // 处理请假请求的抽象方法
    public abstract void processRequest(LeaveRequest request);
}
  1. 实现具体处理器(各级审批者)
dart 复制代码
java
运行
// 具体处理器1:班长(处理≤3天)
public class Monitor extends Approver {
    public Monitor(Approver nextApprover) {
        super(nextApprover);
    }

    @Override
    public void processRequest(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("班长批准" + request.getName() + "请假" + request.getDays() + "天");
        } else {
            // 无法处理,传递给下一个审批者
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理器2:系主任(处理≤7天)
public class Dean extends Approver {
    public Dean(Approver nextApprover) {
        super(nextApprover);
    }

    @Override
    public void processRequest(LeaveRequest request) {
        if (request.getDays() <= 7) {
            System.out.println("系主任批准" + request.getName() + "请假" + request.getDays() + "天");
        } else {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理器3:校长(处理≤30天)
public class Principal extends Approver {
    public Principal(Approver nextApprover) {
        super(nextApprover);
    }

    @Override
    public void processRequest(LeaveRequest request) {
        if (request.getDays() <= 30) {
            System.out.println("校长批准" + request.getName() + "请假" + request.getDays() + "天");
        } else {
            System.out.println(request.getName() + "请假" + request.getDays() + "天,超出最大期限,不批准");
        }
    }
}
  1. 客户端构建责任链并发起请求
dart 复制代码
java
运行
public class Client {
    public static void main(String[] args) {
        // 构建责任链:班长 → 系主任 → 校长(链的末端)
        Approver principal = new Principal(null); // 校长之后无审批者
        Approver dean = new Dean(principal);
        Approver monitor = new Monitor(dean);

        // 发起请求
        LeaveRequest req1 = new LeaveRequest("张三", 2);
        monitor.processRequest(req1); // 班长批准

        LeaveRequest req2 = new LeaveRequest("李四", 5);
        monitor.processRequest(req2); // 系主任批准

        LeaveRequest req3 = new LeaveRequest("王五", 10);
        monitor.processRequest(req3); // 校长批准

        LeaveRequest req4 = new LeaveRequest("赵六", 35);
        monitor.processRequest(req4); // 超出期限,不批准
    }
}

优点

解耦请求发送者与处理者:发送者只需知道链的第一个节点,无需关心后续处理者,降低耦合。

灵活性高:可动态调整链的顺序或增减处理者(符合开放 - 封闭原则)。

单一职责:每个处理者只负责自己能处理的请求,职责清晰。

缺点:

请求可能未被处理:若链中所有处理者都无法处理请求,可能导致请求 "无响应"(需额外处理)。

性能风险:链过长时,请求传递可能导致性能损耗(需合理设计链的长度)。

相关推荐
虫小宝2 天前
基于责任链模式构建可扩展的微信群发消息风控过滤器(Java实现)
android·java·责任链模式
Knight_AL3 天前
设计模式之责任链模式:原理解析 + Java 示例
java·设计模式·责任链模式
Geoking.3 天前
【设计模式】责任链模式(Chain of Responsibility)详解
java·设计模式·责任链模式
Knight_AL3 天前
Spring Boot 中优雅地使用责任链模式(@Order 实战)
windows·spring boot·责任链模式
我是小疯子666 天前
深入解析Rocket框架的FromRequest与责任链模式
责任链模式
__万波__10 天前
二十三种设计模式(二十三)--责任链模式
java·设计模式·责任链模式
罗小爬EX14 天前
杂记 - 状态模式 VS. 责任链模式
状态模式·责任链模式
山风wind18 天前
Spring中责任链模式的工业级应用简单剖析
java·spring·责任链模式
山风wind18 天前
设计模式-责任链模式:让请求在链条中流动直到被处理
设计模式·责任链模式