11. Android 设计模式 核心四之责任链模式 在大型企业级APP的落地

0 阅读19分钟

1.概念

责任链模式(Chain of Responsibility)是一种行为型设计模式,它将请求的发送者和接收者解耦,允许多个对象按顺序处理同一请求。每个处理者(Handler)决定是否处理请求或传递给链中的下一个处理者

核心思想

  • 构建一条处理链,每个节点独立处理或传递请求。
  • 避免请求发送者与接收者直接耦合。

简单的几个字: 顺序,流式处理

2.在Android源码中的应用场景

2.1 事件分发机制
  • 场景描述ViewGroup 到 View 的触摸事件传递。

  • 责任链体现

    • Activity → Window → DecorView → ViewGroup → View
    • 每个节点通过 onTouchEvent() 和 dispatchTouchEvent() 决定是否处理或传递事件。
  • 关键代码

// ViewGroup.dispatchTouchEvent 简化逻辑
public boolean dispatchTouchEvent(MotionEvent ev) {
    for (View child : children) {
        if (child.dispatchTouchEvent(ev)) return true; // 子 View 处理则终止
    }
    return onTouchEvent(ev); // 自身处理
}

2.2 okhttp中的责任链模式的详细分析

  • 拦截器链(Interceptor Chain)

    • 请求处理被拆分为多个拦截器(如缓存、重试、网络 I/O)。
    • 每个拦截器独立处理请求,并可决定是否传递。
  • 工作流程

deepseek_mermaid_20250707_812c39.png

// RealInterceptorChain.proceed()
public Response proceed(Request request) throws IOException {
    // 1. 获取下一个拦截器
    RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1);
    Interceptor interceptor = interceptors.get(index);
    
    // 2. 当前拦截器处理并传递
    Response response = interceptor.intercept(next);
    
    return response;
}
  • 优势:灵活扩展(如添加自定义日志拦截器),符合开闭原则。

下面是一个简化版的 OkHttp 责任链模式实现,包含 5 大核心拦截器,并清晰地展示了递归调用的过程:

package com.example.design.chain.okhttp;

/**
 * @Author pengcaihua
 * @Date 17:24
 * @describe
 */
import java.util.ArrayList;
import java.util.List;

public class OkHttpChainDemo {

    public static void main(String[] args) throws Exception {
        // 创建拦截器链
        List<Interceptor> interceptors = new ArrayList<>();
        interceptors.add(new RetryAndFollowUpInterceptor());
        interceptors.add(new BridgeInterceptor());
        interceptors.add(new CacheInterceptor());
        interceptors.add(new ConnectInterceptor());
        interceptors.add(new CallServerInterceptor());

        // 创建初始请求
        Request request = new Request("https://api.example.com/data");

        // 创建责任链并处理请求
        RealInterceptorChain chain = new RealInterceptorChain(interceptors, 0, request);
        Response response = chain.proceed(request);

        System.out.println("\n最终响应: " + response);
    }

    // 请求类
    static class Request {
        final String url;
        String headers = "";

        Request(String url) {
            this.url = url;
            System.out.println("创建请求: " + url);
        }

        void addHeader(String header) {
            headers += header + "; ";
        }

        @Override
        public String toString() {
            return "Request{url='" + url + "', headers=" + headers + "}";
        }
    }

    // 响应类
    static class Response {
        final Request request;
        String body;
        String headers = "";

        Response(Request request) {
            this.request = request;
        }

        void addHeader(String header) {
            headers += header + "; ";
        }

        void setBody(String body) {
            this.body = body;
        }

        @Override
        public String toString() {
            return "Response{request=" + request + ", headers=" + headers + ", body='" + body + "'}";
        }
    }

    // 拦截器接口
    interface Interceptor {
        Response intercept(Chain chain) throws Exception;
    }

    // 链接口
    interface Chain {
        Request request();
        Response proceed(Request request) throws Exception;
    }

    // 实际拦截器链实现
    static class RealInterceptorChain implements Chain {
        private final List<Interceptor> interceptors;
        private final int index;
        private final Request request;

        RealInterceptorChain(List<Interceptor> interceptors, int index, Request request) {
            this.interceptors = interceptors;
            this.index = index;
            this.request = request;
        }

        @Override
        public Request request() {
            return request;
        }

        @Override
        public Response proceed(Request request) throws Exception {
            // 1. 创建下一个链
            RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1, request);

            // 2. 获取当前拦截器
            Interceptor interceptor = interceptors.get(index);

            // 3. 调用当前拦截器并返回响应
            System.out.println("执行: " + interceptor.getClass().getSimpleName() + " | 调用链深度: " + index);
            return interceptor.intercept(next);
        }
    }

    // ================ 五大拦截器实现 ================

    // 1. 重试和重定向拦截器
    static class RetryAndFollowUpInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws Exception {
            Request request = chain.request();
            System.out.println("  → [Retry] 预处理: 添加重试机制");

            // 添加用户代理头
            request.addHeader("User-Agent: OkHttp");

            // 递归调用下一个拦截器
            System.out.println("  → [Retry] 调用下一个拦截器");
            Response response = chain.proceed(request);

            // 后处理:处理重定向
            System.out.println("  ← [Retry] 后处理: 检查重定向");
            if (response.body != null && response.body.contains("redirect")) {
                System.out.println("  ! [Retry] 检测到重定向");
            }

            return response;
        }
    }

    // 2. 桥接拦截器
    static class BridgeInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws Exception {
            Request request = chain.request();
            System.out.println("    → [Bridge] 预处理: 添加必要头部");

            // 添加必要头信息
            request.addHeader("Accept-Language: zh-CN");
            request.addHeader("Connection: keep-alive");

            System.out.println("    → [Bridge] 调用下一个拦截器");
            Response response = chain.proceed(request);

            System.out.println("    ← [Bridge] 后处理: 解压响应体");
            // 模拟解压响应
            if (response.body != null) {
                response.setBody(response.body.replace("(compressed)", ""));
            }

            return response;
        }
    }

    // 3. 缓存拦截器
    static class CacheInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws Exception {
            Request request = chain.request();
            System.out.println("      → [Cache] 预处理: 检查缓存");

            // 检查缓存
            if (request.url.contains("cached")) {
                System.out.println("      √ [Cache] 找到缓存,直接返回");
                Response cachedResponse = new Response(request);
                cachedResponse.setBody("缓存数据");
                return cachedResponse;
            }

            System.out.println("      → [Cache] 未找到缓存,调用下一个拦截器");
            Response response = chain.proceed(request);

            System.out.println("      ← [Cache] 后处理: 缓存响应");
            // 模拟缓存响应
            if (response.body != null && response.body.length() < 100) {
                System.out.println("      √ [Cache] 缓存响应数据");
            }

            return response;
        }
    }

    // 4. 连接拦截器
    static class ConnectInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws Exception {
            Request request = chain.request();
            System.out.println("        → [Connect] 预处理: 建立连接");

            // 建立连接
            System.out.println("        √ [Connect] 连接到: " + request.url);

            System.out.println("        → [Connect] 调用下一个拦截器");
            Response response = chain.proceed(request);

            System.out.println("        ← [Connect] 后处理: 释放连接资源");
            // 模拟释放资源
            System.out.println("        √ [Connect] 连接已关闭");

            return response;
        }
    }

    // 5. 请求服务拦截器
    static class CallServerInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws Exception {
            Request request = chain.request();
            System.out.println("          → [CallServer] 预处理: 发送网络请求");

            // 模拟网络请求
            System.out.println("          √ [CallServer] 发送请求到服务器");

            // 创建响应 - 这是递归的终点
            Response response = new Response(request);
            response.addHeader("Content-Type: application/json");
            response.addHeader("Server: Nginx");
            response.setBody("(compressed)服务器响应数据");

            System.out.println("          ← [CallServer] 返回响应 (递归终点)");
            return response;
        }
    }
}

okhttp责任链模式的架构图:

deepseek_mermaid_20250707_207230.png

deepseek_mermaid_20250707_ad57c9.png

2.3 Arounter中的责任链模式

  • 场景:路由跳转前的拦截逻辑(如登录验证、权限检查)。

deepseek_mermaid_20250707_207230.png

  • 实现

    • 定义 IInterceptor 接口,实现 process() 方法。
    • 拦截器按优先级排序,依次执行。

工作流程

  • 关键代码
// 拦截器接口
public interface IInterceptor {
    void process(Postcard postcard, InterceptorCallback callback);
}

// 责任链执行
for (IInterceptor interceptor : sortedInterceptors) {
    interceptor.process(postcard, new InterceptorCallback() {
        @Override
        public void onContinue(Postcard postcard) {
            // 继续传递
        }
        @Override
        public void onInterrupt(Throwable exception) {
            // 中断跳转
        }
    });
}

**应用场景**:全局登录拦截器:
@Interceptor(priority = 1)
public class LoginInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
        if (isLogin() || postcard.getPath().equals("/login")) {
            callback.onContinue(postcard); // 已登录或前往登录页 → 放行
        } else {
            callback.onInterrupt(new RuntimeException("未登录"));
        }
    }
}

3.UML图

deepseek_mermaid_20250707_48ce8e.png

4.语音项目的例子和没用设计模式的对比

 语音降噪处理流水线

场景:专业级语音降噪需要多级处理 流程图:

责任链模式通常有两种处理流程实现方式:

单向传递(非递归返回)

public class NonChainAudioProcessing {

    // 处理上下文
    static class ProcessingContext {
        int depth = 0; // 当前调用深度
        boolean terminated = false;
        String terminationReason;

        void enterProcessor(String name) {
            System.out.println(indent(depth) + "→ 进入 " + name);
            depth++;
        }

        void exitProcessor(String name) {
            depth--;
            System.out.println(indent(depth) + "← 返回 " + name);
        }

        void terminate(String reason) {
            terminated = true;
            terminationReason = reason;
        }

        private String indent(int level) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < level; i++) {
                sb.append("  ");  // 每次添加两个空格
            }
            return sb.toString();
        }
    }

    // 音频数据结构
    static class AudioData {
        double snr;
        StringBuilder history = new StringBuilder();

        AudioData(double snr) {
            this.snr = snr;
        }

        void applyFilter(String name, double improvement) {
            snr += improvement;
            history.append(indent(context.depth)).append("├─ ")
                    .append(name).append(" (+").append(improvement).append(" dB)\n");
        }

        private String indent(int level) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < level; i++) {
                sb.append("  ");  // 每次添加两个空格
            }
            return sb.toString();
        }

        @Override
        public String toString() {
            return "音频数据 [SNR: " + snr + " dB]\n处理历史:\n" + history.toString();
        }
    }

    // 处理上下文实例
    private static ProcessingContext context = new ProcessingContext();

    public static void main(String[] args) {
        System.out.println("========= 专业语音降噪处理 =========");
        AudioData audio = new AudioData(10.0); // 初始信噪比10dB

        // 非责任链的递归处理流程
        audio = processAudio(audio);

        System.out.println("\n最终结果:");
        System.out.println(audio);

        if (context.terminated) {
            System.out.println("处理中断原因: " + context.terminationReason);
        }
    }

    // 核心递归处理函数
    private static AudioData processAudio(AudioData input) {
        // 1. 环境噪声检测
        context.enterProcessor("环境噪声检测");
        input = processNoiseDetection(input);
        if (context.terminated) {
            context.exitProcessor("环境噪声检测");
            return input;
        }

        // 2. 回声消除
        context.enterProcessor("回声消除");
        input = processEchoCancellation(input);
        if (context.terminated) {
            context.exitProcessor("回声消除");
            context.exitProcessor("环境噪声检测");
            return input;
        }

        // 3. 频谱降噪
        context.enterProcessor("频谱降噪");
        input = processSpectralReduction(input);
        if (context.terminated) {
            context.exitProcessor("频谱降噪");
            context.exitProcessor("回声消除");
            context.exitProcessor("环境噪声检测");
            return input;
        }

        // 4. 语音增强
        context.enterProcessor("语音增强");
        input = processVoiceEnhancement(input);

        // 5. 动态范围压缩
        context.enterProcessor("动态范围压缩");
        input = processDynamicCompression(input);
        context.exitProcessor("动态范围压缩");

        // 递归返回过程
        context.exitProcessor("语音增强");
        context.exitProcessor("频谱降噪");
        context.exitProcessor("回声消除");
        context.exitProcessor("环境噪声检测");

        return input;
    }

    // 具体处理器实现
    private static AudioData processNoiseDetection(AudioData input) {
        input.applyFilter("环境噪声检测", 5.0);

        // 简单降噪后质量检查
        if (input.snr > 25.0) {
            context.terminate("高质量音频跳过后续处理");
        }

        return input;
    }

    private static AudioData processEchoCancellation(AudioData input) {
        input.applyFilter("回声消除", 8.0);

        // 在回声消除阶段的中断检查
        if (input.snr > 35.0) {
            context.terminate("回声消除后音频质量达标");
        }

        return input;
    }

    private static AudioData processSpectralReduction(AudioData input) {
        input.applyFilter("频谱降噪", 12.0);
        return input;
    }

    private static AudioData processVoiceEnhancement(AudioData input) {
        input.applyFilter("语音增强", 7.0);
        return input;
    }

    private static AudioData processDynamicCompression(AudioData input) {
        input.applyFilter("动态范围压缩", 3.0);
        return input;
    }
}

日志:

2025-07-07 16:56:00.915 19672-19672 System.out              com.evenbus.myapplication            I  ========= 专业语音降噪处理 =========
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  → 进入 环境噪声检测
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I    → 进入 回声消除
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I      → 进入 频谱降噪
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I        → 进入 语音增强
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I          → 进入 动态范围压缩
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I          ← 返回 动态范围压缩
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I        ← 返回 语音增强
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I      ← 返回 频谱降噪
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I    ← 返回 回声消除
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  ← 返回 环境噪声检测
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  最终结果:
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  音频数据 [SNR: 45.0 dB]
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I  处理历史:
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I    ├─ 环境噪声检测 (+5.0 dB)
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I      ├─ 回声消除 (+8.0 dB)
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I        ├─ 频谱降噪 (+12.0 dB)
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I          ├─ 语音增强 (+7.0 dB)
2025-07-07 16:56:00.916 19672-19672 System.out              com.evenbus.myapplication            I            ├─ 动态范围压缩 (+3.0 dB)

递归返回(双向处理)

deepseek_mermaid_20250707_dfd099.png

4.1 不使用责任链模式

不用责任链模式的架构图 :

4.2 使用责任链模式
// ====================== 核心数据结构 ======================
public class AudioData {
    private String rawData;
    private double snr; // 信噪比
    private double[] frequencySpectrum;
    private boolean processed = false;
    private String processingHistory = "";

    public AudioData(String rawData) {
        this.rawData = rawData;
        this.snr = 10.0; // 初始信噪比
    }

    public void applyFilter(String filterName, double snrImprovement) {
        this.snr += snrImprovement;
        this.processed = true;
        processingHistory += " → " + filterName + " (+" + snrImprovement + " dB)";
    }

    public AudioData applyFilter(String filterName) {
        // 模拟处理效果
        System.out.println("    ├─ 应用滤波器: " + filterName);

        // 根据滤波器类型更新状态
        switch (filterName) {
            case "环境噪声检测":
                this.snr += 5.0;
                break;
            case "回声消除":
                this.snr += 8.0;
                break;
            case "频谱降噪":
                this.snr += 12.0;
                break;
            case "语音增强":
                this.snr += 7.0;
                break;
            case "动态范围压缩":
                this.snr += 3.0;
                break;
            case "风噪抑制":
                this.snr += 6.0;
                break;
        }

        this.processed = true;
        return this;
    }

    public double getSNR() {
        return snr;
    }

    public String getStatus() {
        return processed ? "[已处理] SNR: " + String.format("%.1f", snr) + " dB" : "[原始数据]";
    }

    @Override
    public String toString() {
        return "音频数据 " + getStatus();
    }
}
// ====================== 高级处理链构建器 ======================
class AudioProcessingChainBuilder {
    private AudioProcessor first;
    private AudioProcessor current; // 是最后一个

    public AudioProcessingChainBuilder addProcessor(AudioProcessor processor) {
        if (first == null) {
            first = processor;
            current = processor;
        } else {
            current.setNext(processor);
            current = processor;
        }
        return this;
    }

    public AudioProcessor build() { // 拿到第一个
        return first;
    }
}
// ====================== 抽象处理器 ======================
abstract class AudioProcessor {
    protected AudioProcessor next;

    public void setNext(AudioProcessor next) {
        this.next = next;
    }

    public AudioProcessor getNext() {
        return next;
    }

    public AudioData process(AudioData input, ProcessingContext context) {
        System.out.println("→ 进入 " + getProcessorName());

        // 1. 预处理
        AudioData preprocessed = preProcess(input, context);
        context.log("预处理完成: " + preprocessed);

        AudioData result = preprocessed;

        // 2. 传递给下一个处理器(如果存在且未中断)
        if (next != null && !context.shouldTerminate()) {
            context.log("传递给下一处理器: " + next.getProcessorName());
            result = next.process(preprocessed, context);
        }

        // 3. 后处理(递归返回阶段)
        if (!context.shouldTerminate()) {
            AudioData postprocessed = postProcess(result, context);
            context.log("后处理完成: " + postprocessed);
            System.out.println("← 返回 " + getProcessorName() + " | " + postprocessed);
            return postprocessed;
        }

        System.out.println("← 返回 " + getProcessorName() + " [已中断] | " + result);
        return result;
    }

    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        // 默认不进行预处理
        return input;
    }

    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        // 默认不进行后处理
        return input;
    }

    public abstract String getProcessorName();
}
class DynamicRangeCompressor extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "动态范围压缩";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        // 根据音乐/语音类型调整压缩强度
        String audioType = context.get("audioType", String.class);
        String filter = "动态范围压缩";

        if ("music".equals(audioType)) {
            filter = "音乐优化压缩";
        } else if ("voice".equals(audioType)) {
            filter = "语音优化压缩";
        }

        return input.applyFilter(filter);
    }

    @Override
    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        // 收集最终指标
        double originalSNR = context.get("originalSNR", Double.class);
        double finalSNR = input.getSNR();
        double improvement = finalSNR - originalSNR;

        context.log("处理完成!总信噪比提升: " + String.format("%.1f", improvement) + " dB");
        context.put("finalSNR", finalSNR);
        context.put("totalImprovement", improvement);

        return input;
    }
}
class EchoCancellationProcessor extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "回声消除";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        AudioData processed = input.applyFilter("回声消除");

        // 检查是否高质量音频(跳过后续处理)
        if (processed.getSNR() > 40.0) {
            context.terminate("高质量音频跳过后续处理");
            context.log("检测到高质量音频 (SNR: " + processed.getSNR() + " dB),跳过后续处理");
        }

        return processed;
    }

    @Override
    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        // 后处理:轻微增强处理后的音频
        if (input.getSNR() > 25.0) {
            context.log("应用回声消除后增强");
            return input.applyFilter("轻微增强");
        }
        return input;
    }
}
// ====================== 具体处理器实现 ======================
class NoiseDetectionProcessor extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "环境噪声检测";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        context.put("originalSNR", input.getSNR());
        return input.applyFilter("环境噪声检测");
    }

    @Override
    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        double originalSNR = context.get("originalSNR", Double.class);
        double improvement = input.getSNR() - originalSNR;
        context.log("噪声检测完成,信噪比提升: " + String.format("%.1f", improvement) + " dB");
        return input;
    }
}
public class ProcessingContext {
    private Map<String, Object> metadata = new HashMap<>();
    private boolean terminated = false;
    private String terminationReason;
    private Deque<String> callStack = new ArrayDeque<>();

    public void put(String key, Object value) {
        metadata.put(key, value);
    }

    public <T> T get(String key, Class<T> type) {
        return type.cast(metadata.get(key));
    }

    public void terminate(String reason) {
        terminated = true;
        terminationReason = reason;
    }

    public boolean isTerminated() {
        return terminated;
    }

    public String getTerminationReason() {
        return terminationReason;
    }

    public void pushProcessor(String processorName) {
        callStack.push(processorName);
        System.out.println("→ 进入 " + processorName);
    }

    public void popProcessor(String processorName) {
        String popped = callStack.pop();
        if (!popped.equals(processorName)) {
            System.out.println("⚠️ 调用栈错误! 期望弹出 " + processorName + " 但实际弹出 " + popped);
        }
        System.out.println("← 返回 " + processorName);
    }

    public void log(String message) {
        System.out.println("    │  [CONTEXT] " + message);
    }

    public boolean shouldTerminate() {
        return false;
    }
}
class SpectralNoiseReducer extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "频谱降噪";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        // 检测环境类型
        String environment = context.get("environment", String.class);
        if ("windy".equals(environment)) {
            context.log("风噪环境,应用强化降噪");
            return input.applyFilter("强化频谱降噪");
        }
        return input.applyFilter("频谱降噪");
    }

    @Override
    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        // 后处理:分析降噪效果
        double currentSNR = input.getSNR();
        double originalSNR = context.get("originalSNR", Double.class);

        if (currentSNR - originalSNR < 15.0) {
            context.log("降噪效果不足,应用补偿增强");
            return input.applyFilter("补偿增强");
        }
        return input;
    }
}
class VoiceEnhancer extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "语音增强";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        // 根据设备类型调整增强参数
        String deviceType = context.get("deviceType", String.class);
        String filter = "语音增强";

        if ("headset".equals(deviceType)) {
            filter = "耳机优化增强";
        } else if ("car".equals(deviceType)) {
            filter = "车载环境增强";
        }

        return input.applyFilter(filter);
    }

    @Override
    protected AudioData postProcess(AudioData input, ProcessingContext context) {
        // 后处理:添加元数据
        context.put("enhancementApplied", true);
        context.put("finalSNRBeforeCompression", input.getSNR());
        return input;
    }
}
class WindNoiseSuppressor extends AudioProcessor {
    @Override
    public String getProcessorName() {
        return "风噪抑制";
    }

    @Override
    protected AudioData preProcess(AudioData input, ProcessingContext context) {
        // 只有在风噪环境中才处理
        if ("windy".equals(context.get("environment", String.class))) {
            context.log("检测到风噪环境,应用风噪抑制");
            return input.applyFilter("风噪抑制");
        }
        context.log("无风噪环境,跳过处理");
        return input;
    }
}
// ====================== 客户端使用示例 ======================
public class ProfessionalAudioProcessing {
    public static void main(String[] args) {
        // 场景1:标准语音处理
        System.out.println("==================== 场景1: 标准语音处理 ====================");
        processAudioScenario("办公室会议录音", "office", "voice", "built-in");

//        // 场景2:风噪环境中的车载处理
//        System.out.println("\n==================== 场景2: 风噪环境车载处理 ====================");
//        processAudioScenario("车载免提通话", "windy", "voice", "car");
//
//        // 场景3:高质量音频跳过处理
//        System.out.println("\n==================== 场景3: 高质量音频处理 ====================");
//        processHighQualityAudio("录音室高质量音频", "studio", "music", "studio");
    }

    private static void processAudioScenario(String description, String environment,
                                             String audioType, String deviceType) {
        System.out.println("处理: " + description);
        System.out.println("环境: " + environment + " | 音频类型: " + audioType + " | 设备: " + deviceType);

        // 1. 创建处理链
        AudioProcessor chain = new AudioProcessingChainBuilder()
                .addProcessor(new NoiseDetectionProcessor())
                .addProcessor(new WindNoiseSuppressor()) // 根据环境条件可能跳过
                .addProcessor(new EchoCancellationProcessor())
                .addProcessor(new SpectralNoiseReducer())
                .addProcessor(new VoiceEnhancer())
                .addProcessor(new DynamicRangeCompressor())
                .build();

        // 2. 准备上下文
        ProcessingContext context = new ProcessingContext();
        context.put("environment", environment);
        context.put("audioType", audioType);
        context.put("deviceType", deviceType);

        // 3. 执行处理
        AudioData rawAudio = new AudioData("原始音频数据");
        System.out.println("开始处理: " + rawAudio);
        AudioData result = chain.process(rawAudio, context);

        // 4. 输出结果
        System.out.println("\n处理结果: " + result);
        if (context.shouldTerminate()) {
            System.out.println("! 处理被中断: " + context.getTerminationReason());
        }
        System.out.println("最终信噪比: " + context.get("finalSNR", Double.class) + " dB");
        System.out.println("总提升: " + context.get("totalImprovement", Double.class) + " dB\n");
    }

    private static void processHighQualityAudio(String description, String environment,
                                                String audioType, String deviceType) {
        System.out.println("处理: " + description);

        // 创建处理链
        AudioProcessor chain = new AudioProcessingChainBuilder()
                .addProcessor(new NoiseDetectionProcessor())
                .addProcessor(new EchoCancellationProcessor()) // 这里会检测到高质量音频并中断
                .addProcessor(new SpectralNoiseReducer())
                .build();

        // 准备上下文
        ProcessingContext context = new ProcessingContext();
        context.put("environment", environment);
        context.put("audioType", audioType);
        context.put("deviceType", deviceType);

        // 创建高质量音频(信噪比初始设为45dB)
        AudioData highQualityAudio = new AudioData("高质量音频数据") {
            @Override
            public double getSNR() {
                return 45.0; // 高质量音频
            }
        };

        System.out.println("开始处理: " + highQualityAudio);
        AudioData result = chain.process(highQualityAudio, context);

        System.out.println("\n处理结果: " + result);
        System.out.println("! 处理被中断: " + context.getTerminationReason());
        System.out.println("最终信噪比: " + highQualityAudio.getSNR() + " dB (保持不变)");
    }
}

日志:

2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I  ==================== 场景1: 标准语音处理 ====================
2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I  处理: 办公室会议录音
2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I  环境: office | 音频类型: voice | 设备: built-in
2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I  开始处理: 音频数据 [原始数据]
2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 环境噪声检测
2025-07-07 16:39:01.271 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 环境噪声检测
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 15.0 dB
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 传递给下一处理器: 风噪抑制
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 风噪抑制
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 无风噪环境,跳过处理
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 15.0 dB
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 传递给下一处理器: 回声消除
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 回声消除
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 回声消除
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 23.0 dB
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 传递给下一处理器: 频谱降噪
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 频谱降噪
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 频谱降噪
2025-07-07 16:39:01.272 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 35.0 dB
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 传递给下一处理器: 语音增强
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 语音增强
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 语音增强
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 传递给下一处理器: 动态范围压缩
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I  → 进入 动态范围压缩
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 语音优化压缩
2025-07-07 16:39:01.273 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 预处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.274 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 处理完成!总信噪比提升: 32.0 dB
2025-07-07 16:39:01.274 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.274 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 动态范围压缩 | 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.274 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 语音增强 | 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 频谱降噪 | 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 应用回声消除后增强
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I      ├─ 应用滤波器: 轻微增强
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.275 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 回声消除 | 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.276 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.276 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 风噪抑制 | 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.276 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 噪声检测完成,信噪比提升: 32.0 dB
2025-07-07 16:39:01.276 16895-16895 System.out              com.evenbus.myapplication            I[CONTEXT] 后处理完成: 音频数据 [已处理] SNR: 42.0 dB
2025-07-07 16:39:01.276 16895-16895 System.out              com.evenbus.myapplication            I  ← 返回 环境噪声检测 | 音频数据 [已处理] SNR: 42.0 dB

用责任链模式的架构图 :

deepseek_mermaid_20250707_ad57c9.png

好处

  1. 新增处理步骤(如风噪抑制)需修改 process() 方法 开闭原则 新增处理器只需实现 AudioProcessor 接口:

  2. 无法动态调整处理顺序(如移动环境下先做风噪抑制) 灵活组合

  3. 双向处理

    • 预处理(添加头信息、缓存检查)
    • 后处理(解压响应、缓存存储)

5.优点

  1. 灵活扩展:通过添加拦截器实现功能扩展(如日志、埋点),无需修改核心代码。
  2. 动态排序:拦截器优先级(priority)可控制执行顺序。
  3. 单一职责:每个拦截器只关注自身逻辑(如登录验证无需感知权限检查)。
  4. 流程可控:支持中断跳转(如未登录时拦截并跳转登录页)。

6.和相似的设计模式的区别

组合模式的区别 责任链模式和组合模式虽然都涉及多个对象的协作,但解决的是完全不同的问题:

  • 责任链模式关注请求的传递和处理,强调请求在对象链上的流动
  • 组合模式关注对象的结构组织,强调部分与整体的层次关系

总结

  • 责任链模式适用场景:多步骤处理流程、需动态扩展处理逻辑的模块(如网络请求、路由跳转)。

  • Android 实战要点

    • 优先使用接口定义处理者(如 Interceptor)。
    • 通过 setNext() 方法构建链式关系。
    • 结合优先级(如 ARouter 的 priority)控制执行顺序。
  • 避坑指南:避免循环引用,确保链终结点能处理所有未捕获请求。

项目的地址: github.com/pengcaihua1…