深入理解责任链模式:从HTTP中间件到异常处理的实战应用

深入理解责任链模式:从HTTP中间件到异常处理的实战应用


🌟 嗨,我是IRpickstars!

🌌 总有一行代码,能点亮万千星辰。

🔍 在技术的宇宙中,我愿做永不停歇的探索者。

✨ 用代码丈量世界,用算法解码未来。我是摘星人,也是造梦者。

🚀 每一次编译都是新的征程,每一个bug都是未解的谜题。让我们携手,在0和1的星河中,书写属于开发者的浪漫诗篇。


目录

深入理解责任链模式:从HTTP中间件到异常处理的实战应用

摘要

一、责任链模式概述

[1.1 模式定义](#1.1 模式定义)

[1.2 核心思想](#1.2 核心思想)

[1.3 模式结构](#1.3 模式结构)

二、UML类图设计

三、责任链模式的标准实现

[3.1 Java实现](#3.1 Java实现)

[3.2 Python实现](#3.2 Python实现)

四、HTTP请求中间件实现

[4.1 中间件架构设计](#4.1 中间件架构设计)

[4.2 Java实现HTTP中间件](#4.2 Java实现HTTP中间件)

五、异常处理责任链应用

[5.1 异常处理流程设计](#5.1 异常处理流程设计)

[5.2 异常处理链实现](#5.2 异常处理链实现)

六、模式优缺点分析

[6.1 优点](#6.1 优点)

[6.2 缺点](#6.2 缺点)

七、适用场景与最佳实践

[7.1 适用场景](#7.1 适用场景)

[7.2 最佳实践](#7.2 最佳实践)

八、参考资源

总结


摘要

作为一名有着多年开发经验的程序员,我在日常的项目开发中经常遇到这样的场景:一个请求需要经过多个处理步骤,比如身份验证、权限检查、参数校验、业务逻辑处理等。最初我会写很多if-else判断,代码变得越来越复杂,维护起来也越来越困难。直到我深入学习了设计模式,特别是责任链模式(Chain of Responsibility),才发现原来可以如此优雅地处理这类问题。

责任链模式在现代软件开发中占据着重要地位,尤其在Web开发、中间件设计、异常处理等领域应用广泛。我在实际项目中运用责任链模式构建了HTTP请求处理中间件,将原本耦合度极高的请求处理逻辑解耦成独立的处理节点,不仅提高了代码的可维护性,还大大增强了系统的扩展性。在异常处理方面,责任链模式让我能够构建层次化的异常处理机制,不同类型的异常由不同的处理器处理,避免了传统try-catch嵌套带来的代码混乱。

本文将深入探讨责任链模式的核心原理,从理论基础到实践应用,通过HTTP中间件和异常处理两个典型场景,帮助大家真正掌握这一重要的设计模式。

一、责任链模式概述

1.1 模式定义

责任链模式是一种行为型设计模式,它为请求创建了一个接收者对象的链。这种模式给请求的发送者和接收者解耦,让多个对象都有机会处理请求。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

1.2 核心思想

责任链模式的核心思想是"将请求沿处理链传递,直到有对象处理它"。这种设计理念体现了以下几个重要原则:

  • 单一职责原则:每个处理器只负责自己能处理的请求类型
  • 开闭原则:可以动态地添加或删除处理器而不影响其他代码
  • 松耦合:请求发送者不需要知道谁会处理请求

1.3 模式结构

责任链模式包含以下核心角色:

  • Handler(抽象处理者):定义处理请求的接口,包含后继连接
  • ConcreteHandler(具体处理者):实现处理请求的具体逻辑
  • Client(客户端):创建处理链并提交请求

二、UML类图设计

图1:责任链模式UML类图

三、责任链模式的标准实现

3.1 Java实现

java 复制代码
// 抽象处理者
abstract class Handler {
    protected Handler successor; // 后继处理者
    
    /**
     * 设置后继处理者
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
    /**
     * 处理请求的抽象方法
     */
    public abstract void handleRequest(Request request);
}

// 请求类
class Request {
    private String type;    // 请求类型
    private String content; // 请求内容
    
    public Request(String type, String content) {
        this.type = type;
        this.content = content;
    }
    
    // getter和setter方法
    public String getType() { return type; }
    public String getContent() { return content; }
}

// 具体处理者A - 处理认证请求
class AuthenticationHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if ("AUTH".equals(request.getType())) {
            System.out.println("认证处理器:处理认证请求 - " + request.getContent());
        } else if (successor != null) {
            // 传递给下一个处理者
            successor.handleRequest(request);
        }
    }
}

// 具体处理者B - 处理授权请求
class AuthorizationHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if ("AUTHZ".equals(request.getType())) {
            System.out.println("授权处理器:处理授权请求 - " + request.getContent());
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 具体处理者C - 处理业务请求
class BusinessHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if ("BUSINESS".equals(request.getType())) {
            System.out.println("业务处理器:处理业务请求 - " + request.getContent());
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 客户端代码
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // 创建处理者
        Handler authHandler = new AuthenticationHandler();
        Handler authzHandler = new AuthorizationHandler();
        Handler businessHandler = new BusinessHandler();
        
        // 构建责任链
        authHandler.setSuccessor(authzHandler);
        authzHandler.setSuccessor(businessHandler);
        
        // 发送不同类型的请求
        Request authRequest = new Request("AUTH", "用户登录验证");
        Request authzRequest = new Request("AUTHZ", "权限检查");
        Request businessRequest = new Request("BUSINESS", "订单处理");
        
        // 处理请求
        authHandler.handleRequest(authRequest);
        authHandler.handleRequest(authzRequest);
        authHandler.handleRequest(businessRequest);
    }
}

3.2 Python实现

java 复制代码
from abc import ABC, abstractmethod
from typing import Optional

class Request:
    """请求类"""
    def __init__(self, request_type: str, content: str):
        self.type = request_type
        self.content = content

class Handler(ABC):
    """抽象处理者"""
    def __init__(self):
        self._successor: Optional[Handler] = None
    
    def set_successor(self, successor: 'Handler') -> None:
        """设置后继处理者"""
        self._successor = successor
    
    @abstractmethod
    def handle_request(self, request: Request) -> None:
        """处理请求的抽象方法"""
        pass

class AuthenticationHandler(Handler):
    """认证处理器"""
    def handle_request(self, request: Request) -> None:
        if request.type == "AUTH":
            print(f"认证处理器:处理认证请求 - {request.content}")
        elif self._successor:
            self._successor.handle_request(request)

class AuthorizationHandler(Handler):
    """授权处理器"""
    def handle_request(self, request: Request) -> None:
        if request.type == "AUTHZ":
            print(f"授权处理器:处理授权请求 - {request.content}")
        elif self._successor:
            self._successor.handle_request(request)

class BusinessHandler(Handler):
    """业务处理器"""
    def handle_request(self, request: Request) -> None:
        if request.type == "BUSINESS":
            print(f"业务处理器:处理业务请求 - {request.content}")
        elif self._successor:
            self._successor.handle_request(request)

def main():
    """客户端代码"""
    # 创建处理者
    auth_handler = AuthenticationHandler()
    authz_handler = AuthorizationHandler()
    business_handler = BusinessHandler()
    
    # 构建责任链
    auth_handler.set_successor(authz_handler)
    authz_handler.set_successor(business_handler)
    
    # 创建并处理请求
    requests = [
        Request("AUTH", "用户登录验证"),
        Request("AUTHZ", "权限检查"),
        Request("BUSINESS", "订单处理")
    ]
    
    for req in requests:
        auth_handler.handle_request(req)

if __name__ == "__main__":
    main()

四、HTTP请求中间件实现

4.1 中间件架构设计

在Web开发中,HTTP请求处理是责任链模式的典型应用场景。我们可以将各种处理逻辑(如CORS处理、身份验证、日志记录等)封装成独立的中间件。

图2:HTTP中间件处理流程图

4.2 Java实现HTTP中间件

java 复制代码
// HTTP请求和响应的简化版本
class HttpRequest {
    private String method;
    private String path;
    private Map<String, String> headers;
    private String body;
    
    public HttpRequest(String method, String path) {
        this.method = method;
        this.path = path;
        this.headers = new HashMap<>();
    }
    
    // getter和setter方法
    public String getMethod() { return method; }
    public String getPath() { return path; }
    public Map<String, String> getHeaders() { return headers; }
    public void addHeader(String key, String value) { headers.put(key, value); }
    public String getBody() { return body; }
    public void setBody(String body) { this.body = body; }
}

class HttpResponse {
    private int statusCode;
    private Map<String, String> headers;
    private String body;
    
    public HttpResponse() {
        this.headers = new HashMap<>();
        this.statusCode = 200;
    }
    
    // getter和setter方法
    public int getStatusCode() { return statusCode; }
    public void setStatusCode(int statusCode) { this.statusCode = statusCode; }
    public Map<String, String> getHeaders() { return headers; }
    public void addHeader(String key, String value) { headers.put(key, value); }
    public String getBody() { return body; }
    public void setBody(String body) { this.body = body; }
}

// HTTP中间件接口
interface HttpMiddleware {
    /**
     * 处理HTTP请求
     * @param request HTTP请求
     * @param response HTTP响应
     * @param next 下一个中间件
     */
    void handle(HttpRequest request, HttpResponse response, Runnable next);
}

// CORS中间件
class CorsMiddleware implements HttpMiddleware {
    @Override
    public void handle(HttpRequest request, HttpResponse response, Runnable next) {
        System.out.println("CORS中间件:处理跨域请求");
        
        // 添加CORS头
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        
        // 如果是OPTIONS请求,直接返回
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatusCode(200);
            return;
        }
        
        // 继续处理下一个中间件
        next.run();
    }
}

// 认证中间件
class AuthenticationMiddleware implements HttpMiddleware {
    @Override
    public void handle(HttpRequest request, HttpResponse response, Runnable next) {
        System.out.println("认证中间件:验证用户身份");
        
        String authHeader = request.getHeaders().get("Authorization");
        
        // 简单的认证逻辑
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            response.setStatusCode(401);
            response.setBody("Unauthorized: Missing or invalid token");
            return;
        }
        
        // 验证通过,继续下一个中间件
        System.out.println("认证成功,用户身份验证通过");
        next.run();
    }
}

// 日志中间件
class LoggingMiddleware implements HttpMiddleware {
    @Override
    public void handle(HttpRequest request, HttpResponse response, Runnable next) {
        long startTime = System.currentTimeMillis();
        
        System.out.println("日志中间件:记录请求开始 - " + 
                          request.getMethod() + " " + request.getPath());
        
        // 处理下一个中间件
        next.run();
        
        long endTime = System.currentTimeMillis();
        System.out.println("日志中间件:记录请求结束 - 耗时: " + 
                          (endTime - startTime) + "ms, 状态码: " + response.getStatusCode());
    }
}

// 业务处理中间件
class BusinessMiddleware implements HttpMiddleware {
    @Override
    public void handle(HttpRequest request, HttpResponse response, Runnable next) {
        System.out.println("业务中间件:处理业务逻辑");
        
        // 模拟业务处理
        if ("/api/users".equals(request.getPath())) {
            response.setBody("{\"users\": [\"Alice\", \"Bob\", \"Charlie\"]}");
            response.addHeader("Content-Type", "application/json");
        } else {
            response.setStatusCode(404);
            response.setBody("Not Found");
        }
    }
}

// 中间件管理器
class MiddlewareManager {
    private List<HttpMiddleware> middlewares = new ArrayList<>();
    
    public void addMiddleware(HttpMiddleware middleware) {
        middlewares.add(middleware);
    }
    
    public void processRequest(HttpRequest request, HttpResponse response) {
        processMiddleware(0, request, response);
    }
    
    private void processMiddleware(int index, HttpRequest request, HttpResponse response) {
        if (index >= middlewares.size()) {
            return; // 所有中间件都处理完毕
        }
        
        HttpMiddleware middleware = middlewares.get(index);
        middleware.handle(request, response, () -> {
            // 只有当前中间件调用next()时,才会处理下一个中间件
            processMiddleware(index + 1, request, response);
        });
    }
}

// 使用示例
public class HttpMiddlewareDemo {
    public static void main(String[] args) {
        // 创建中间件管理器
        MiddlewareManager manager = new MiddlewareManager();
        
        // 添加中间件(注意顺序很重要)
        manager.addMiddleware(new CorsMiddleware());
        manager.addMiddleware(new AuthenticationMiddleware());
        manager.addMiddleware(new LoggingMiddleware());
        manager.addMiddleware(new BusinessMiddleware());
        
        // 模拟HTTP请求
        HttpRequest request = new HttpRequest("GET", "/api/users");
        request.addHeader("Authorization", "Bearer valid-token-123");
        
        HttpResponse response = new HttpResponse();
        
        // 处理请求
        System.out.println("=== 处理HTTP请求 ===");
        manager.processRequest(request, response);
        
        System.out.println("\n=== 响应结果 ===");
        System.out.println("状态码: " + response.getStatusCode());
        System.out.println("响应体: " + response.getBody());
    }
}

五、异常处理责任链应用

5.1 异常处理流程设计

在复杂的应用系统中,异常处理往往需要分层处理,不同类型的异常由不同的处理器负责。

图3:异常处理责任链流程图

5.2 异常处理链实现

java 复制代码
// 异常处理结果
class ExceptionResult {
    private int errorCode;
    private String errorMessage;
    private boolean handled;
    
    public ExceptionResult(int errorCode, String errorMessage, boolean handled) {
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.handled = handled;
    }
    
    // getter方法
    public int getErrorCode() { return errorCode; }
    public String getErrorMessage() { return errorMessage; }
    public boolean isHandled() { return handled; }
}

// 抽象异常处理器
abstract class ExceptionHandler {
    protected ExceptionHandler nextHandler;
    
    public void setNext(ExceptionHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
    
    /**
     * 处理异常
     */
    public ExceptionResult handleException(Exception exception) {
        // 检查是否可以处理该异常
        if (canHandle(exception)) {
            return doHandle(exception);
        }
        
        // 传递给下一个处理器
        if (nextHandler != null) {
            return nextHandler.handleException(exception);
        }
        
        // 没有处理器能处理该异常
        return new ExceptionResult(500, "未知异常", false);
    }
    
    /**
     * 判断是否能处理该异常
     */
    protected abstract boolean canHandle(Exception exception);
    
    /**
     * 具体的异常处理逻辑
     */
    protected abstract ExceptionResult doHandle(Exception exception);
}

// 自定义业务异常
class BusinessException extends Exception {
    private int errorCode;
    
    public BusinessException(int errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
    
    public int getErrorCode() { return errorCode; }
}

// 业务异常处理器
class BusinessExceptionHandler extends ExceptionHandler {
    @Override
    protected boolean canHandle(Exception exception) {
        return exception instanceof BusinessException;
    }
    
    @Override
    protected ExceptionResult doHandle(Exception exception) {
        BusinessException bizException = (BusinessException) exception;
        
        System.out.println("业务异常处理器:处理业务异常");
        System.out.println("错误码: " + bizException.getErrorCode());
        System.out.println("错误信息: " + bizException.getMessage());
        
        // 记录业务日志
        logBusinessError(bizException);
        
        return new ExceptionResult(
            bizException.getErrorCode(), 
            bizException.getMessage(), 
            true
        );
    }
    
    private void logBusinessError(BusinessException exception) {
        System.out.println("[业务日志] 业务异常: " + exception.getMessage());
    }
}

// 系统异常处理器
class SystemExceptionHandler extends ExceptionHandler {
    @Override
    protected boolean canHandle(Exception exception) {
        return exception instanceof RuntimeException || 
               exception instanceof IllegalArgumentException ||
               exception instanceof NullPointerException;
    }
    
    @Override
    protected ExceptionResult doHandle(Exception exception) {
        System.out.println("系统异常处理器:处理系统异常");
        System.out.println("异常类型: " + exception.getClass().getSimpleName());
        System.out.println("异常信息: " + exception.getMessage());
        
        // 记录系统错误日志
        logSystemError(exception);
        
        return new ExceptionResult(
            500, 
            "系统内部错误,请稍后重试", 
            true
        );
    }
    
    private void logSystemError(Exception exception) {
        System.out.println("[系统日志] 系统异常: " + exception.getClass().getSimpleName() + 
                          " - " + exception.getMessage());
    }
}

// 网络异常处理器
class NetworkExceptionHandler extends ExceptionHandler {
    @Override
    protected boolean canHandle(Exception exception) {
        return exception instanceof java.net.SocketException ||
               exception instanceof java.net.ConnectException ||
               exception.getMessage().contains("network") ||
               exception.getMessage().contains("timeout");
    }
    
    @Override
    protected ExceptionResult doHandle(Exception exception) {
        System.out.println("网络异常处理器:处理网络异常");
        System.out.println("网络错误: " + exception.getMessage());
        
        // 记录网络错误并可能触发重试机制
        logNetworkError(exception);
        
        return new ExceptionResult(
            503, 
            "网络连接失败,请检查网络连接", 
            true
        );
    }
    
    private void logNetworkError(Exception exception) {
        System.out.println("[网络日志] 网络异常: " + exception.getMessage());
    }
}

// 默认异常处理器(兜底处理器)
class DefaultExceptionHandler extends ExceptionHandler {
    @Override
    protected boolean canHandle(Exception exception) {
        return true; // 处理所有未被其他处理器处理的异常
    }
    
    @Override
    protected ExceptionResult doHandle(Exception exception) {
        System.out.println("默认异常处理器:处理未知异常");
        System.out.println("未知异常: " + exception.getClass().getSimpleName());
        
        // 记录致命错误日志
        logFatalError(exception);
        
        return new ExceptionResult(
            500, 
            "系统发生未知错误", 
            true
        );
    }
    
    private void logFatalError(Exception exception) {
        System.out.println("[致命错误日志] 未处理异常: " + exception.toString());
        exception.printStackTrace();
    }
}

// 异常处理链管理器
class ExceptionChainManager {
    private ExceptionHandler firstHandler;
    
    public ExceptionChainManager() {
        buildChain();
    }
    
    private void buildChain() {
        // 构建异常处理链
        ExceptionHandler businessHandler = new BusinessExceptionHandler();
        ExceptionHandler networkHandler = new NetworkExceptionHandler();
        ExceptionHandler systemHandler = new SystemExceptionHandler();
        ExceptionHandler defaultHandler = new DefaultExceptionHandler();
        
        // 设置处理链顺序:业务异常 -> 网络异常 -> 系统异常 -> 默认处理
        businessHandler.setNext(networkHandler);
        networkHandler.setNext(systemHandler);
        systemHandler.setNext(defaultHandler);
        
        this.firstHandler = businessHandler;
    }
    
    public ExceptionResult handleException(Exception exception) {
        return firstHandler.handleException(exception);
    }
}

// 使用示例
public class ExceptionChainDemo {
    public static void main(String[] args) {
        ExceptionChainManager manager = new ExceptionChainManager();
        
        // 测试不同类型的异常
        Exception[] exceptions = {
            new BusinessException(1001, "用户名不能为空"),
            new NullPointerException("空指针异常"),
            new java.net.ConnectException("连接超时"),
            new Exception("未知类型异常")
        };
        
        for (Exception exception : exceptions) {
            System.out.println("\n=== 处理异常: " + exception.getClass().getSimpleName() + " ===");
            ExceptionResult result = manager.handleException(exception);
            
            System.out.println("处理结果:");
            System.out.println("- 错误码: " + result.getErrorCode());
            System.out.println("- 错误信息: " + result.getErrorMessage());
            System.out.println("- 是否已处理: " + result.isHandled());
            System.out.println();
        }
    }
}

六、模式优缺点分析

6.1 优点

  1. 降低耦合度:请求发送者和接收者之间解耦,发送者不需要知道链的结构和接收者的具体信息
  2. 增强扩展性:可以动态地增加或删除处理者,符合开闭原则
  3. 增强职责分配的灵活性:每个处理者专注于自己的职责,职责单一
  4. 简化对象间连接:对象只需要保持对后继者的引用,简化了对象间的相互连接

6.2 缺点

  1. 性能影响:请求可能需要遍历整个链才能被处理,影响性能
  2. 调试困难:责任链较长时,调试和排错比较困难
  3. 不保证处理:如果链配置不当,可能导致请求无法被处理

七、适用场景与最佳实践

7.1 适用场景

  1. 有多个对象可以处理同一请求:如权限验证、日志记录等
  2. 需要动态指定处理者:运行时决定由哪个对象处理请求
  3. 不明确指定接收者:希望多个对象中的一个处理请求,但不明确指定接收者

7.2 最佳实践

  1. 合理设计链的长度:避免链过长影响性能
  2. 提供默认处理者:确保请求总能得到处理
  3. 注意处理者的顺序:将最有可能处理请求的处理者放在链的前面
  4. 避免循环引用:确保链不会形成环路

八、参考资源

以下是一些权威的参考资源,帮助深入学习责任链模式:

  1. GoF设计模式官方文档
    • Gang of Four Design Patterns: Chain of Responsibility
    • 《设计模式:可复用面向对象软件的基础》
  1. Spring Framework源码参考
  1. 开源项目示例
  1. 技术博客和文档
    • Martin Fowler的企业应用架构模式
    • Oracle Java设计模式文档
    • Baeldung责任链模式教程

总结

通过这篇文章的深入探讨,我对责任链模式有了更加全面和深刻的理解。从最初的概念学习到实际项目应用,责任链模式确实为我的开发工作带来了很大的便利。

在我的实际项目经验中,责任链模式最大的价值在于它能够优雅地处理复杂的业务流程。特别是在构建HTTP中间件系统时,我深刻体会到了这种模式的强大之处。原本需要在一个方法中处理认证、授权、日志、业务逻辑等多种关注点,现在可以将每个关注点独立成一个中间件,不仅代码更加清晰,而且维护和扩展都变得非常容易。当需要添加新的处理逻辑时,只需要实现一个新的中间件并插入到合适的位置即可,完全不需要修改现有代码。

在异常处理方面,责任链模式让我摆脱了传统的多层try-catch嵌套的困扰。通过构建分层的异常处理链,不同类型的异常由专门的处理器负责,不仅提高了代码的可读性,还让异常处理逻辑更加统一和规范。特别是在微服务架构中,这种模式可以很好地处理来自不同服务的各种异常情况。

对于想要学习和应用责任链模式的开发者,我建议首先理解模式的核心思想,然后从简单的场景开始实践,比如实现一个简单的审批流程或者日志处理链。在实际应用中,要特别注意链的设计,避免链过长导致的性能问题,同时要确保提供兜底的默认处理器。

展望未来,随着微服务架构的普及和云原生技术的发展,责任链模式在分布式系统中的应用将会更加广泛。无论是API网关的请求处理、服务间的调用链路追踪,还是分布式事务的处理,责任链模式都将发挥重要作用。我相信掌握好这个模式,对提升我们在复杂系统设计方面的能力具有重要意义。

希望这篇文章能够帮助大家更好地理解和运用责任链模式,在实际项目中写出更加优雅、可维护的代码。

🌟 嗨,我是IRpickstars!如果你觉得这篇技术分享对你有启发:

🛠️ 点击【点赞】让更多开发者看到这篇干货

🔔 【关注】解锁更多架构设计&性能优化秘籍

💡 【评论】留下你的技术见解或实战困惑

作为常年奋战在一线的技术博主,我特别期待与你进行深度技术对话。每一个问题都是新的思考维度,每一次讨论都能碰撞出创新的火花。
🌟 点击这里👉 IRpickstars的主页 ,获取最新技术解析与实战干货!

⚡️ 我的更新节奏:

  • 每周三晚8点:深度技术长文
  • 每周日早10点:高效开发技巧
  • 突发技术热点:48小时内专题解析
相关推荐
GodKeyNet1 小时前
设计模式-责任链模式
java·设计模式·责任链模式
G等你下课3 小时前
AJAX请求跨域问题
前端·javascript·http
用户8762191062456 小时前
【计算机网络】HTTP 版本
http
拾光拾趣录6 小时前
无状态协议下的用户状态管理:Web应用如何保持用户登录态
前端·http·https
鼠鼠我呀28 小时前
【设计模式04】单例模式
单例模式·设计模式
游戏开发爱好者814 小时前
iOS重构期调试实战:架构升级中的性能与数据保障策略
websocket·网络协议·tcp/ip·http·网络安全·https·udp
缘来是庄17 小时前
设计模式之访问者模式
java·设计模式·访问者模式
hqxstudying19 小时前
Java创建型模式---单例模式
java·数据结构·设计模式·代码规范
花好月圆春祺夏安20 小时前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式