过滤器模式、责任链模式

过滤器模式

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

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

比如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); // 超出期限,不批准
    }
}

优点

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

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

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

缺点:

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

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

相关推荐
ZHE|张恒2 天前
设计模式实战篇(五):责任链模式 — 把复杂审批/过滤流程变成可组合的“传递链”
设计模式·责任链模式
CodeAmaz2 天前
使用责任链模式设计电商下单流程(Java 实战)
java·后端·设计模式·责任链模式·下单
海棠Flower未眠13 天前
SpringBoot 项目基于责任链模式实现复杂接口的解耦和动态编排
责任链模式
Query*1 个月前
Java 设计模式—— 责任链模式:从原理到 SpringBoot 最优实现
java·spring boot·责任链模式
凸头1 个月前
责任链模式
java·开发语言·责任链模式
Mr_WangAndy1 个月前
C++设计模式_行为型模式_责任链模式Chain of Responsibility
c++·设计模式·责任链模式·行为型模式
星空寻流年1 个月前
设计模式第七章(责任链模式)
设计模式·责任链模式
NiKo_W1 个月前
Linux 进程通信——基于责任链模式的消息队列
linux·服务器·消息队列·责任链模式·进程通信
Meteors.1 个月前
23种设计模式——责任链模式(Chain of Responsibility Pattern)
设计模式·责任链模式