0

0

Golang责任链模式和中间件链有什么区别_设计模式对比说明

P粉602998670

P粉602998670

发布时间:2026-01-23 15:49:02

|

725人浏览过

|

来源于php中文网

原创

中间件链是责任链模式在HTTP场景的特化实现,二者为“模式vs实现”关系:责任链通用,中间件链专用于HTTP请求处理,核心均依赖函数组合与显式next调用控制流程。

golang责任链模式和中间件链有什么区别_设计模式对比说明

责任链模式和中间件链在 Go 里本质是同一思想的两种表达:中间件链是责任链在 HTTP 请求处理场景下的具体落地,不是并列关系,而是“模式 vs 实现”的关系。

为什么说中间件链是责任链的特化实现

责任链模式定义了一组处理器(Handler),每个决定是否处理请求、是否传递给下一个——这完全对应 http.Handler 中间件的结构:func(http.Handler) http.Handler。Go 标准库不提供抽象基类,所以没有显式的 Handler 接口继承链,但通过函数签名统一、手动嵌套调用,自然形成了链式结构。

  • 责任链强调“请求沿链传递,可跳过/终止/继续”,中间件链中每个中间件调用 next.ServeHTTP() 就是“继续”;不调用即“终止”(如认证失败直接 http.Error
  • 两者都依赖“后添加、先执行”的洋葱模型(即包装顺序与执行顺序相反),这是链式调用的核心约束
  • 责任链可应用于任意场景(如审批流、日志分级、错误分类),而中间件链专指 HTTP 请求生命周期的装饰与拦截

实际编码中容易混淆的三个点

开发者常把“写了个中间件”当成“实现了责任链”,但真正踩坑往往出在结构误用上:

  • 误把中间件当独立组件复用:一个 loggingMiddleware 函数本身不是责任链节点,只有被套进 handler → mw1 → mw2 → final 这个嵌套结构里,才构成链。单独调用它不会触发链行为
  • 忽略执行顺序反直觉性:写 chainMiddleware(a, b, c) 时,c 最先执行(最外层包装),a 最后执行(最内层)。若按“注册顺序即执行顺序”理解,就会在 CORS 和 auth 的先后逻辑上出错
  • 混用框架中间件签名:Gin 的 gin.HandlerFuncfunc(*gin.Context),而标准库是 func(http.ResponseWriter, *http.Request)。强行把 Gin 中间件塞进 net/http 链会编译失败——它们属于不同责任链实例,不可跨生态混搭

什么时候该自己手写链,而不是用框架

当你需要极简依赖、明确控制流、或嵌入非 HTTP 场景(比如配置加载、事件分发、命令解析)时,手写责任链更合适。例如:

Asksia
Asksia

Asksia AI - 最好的AI老师,可靠的作业助手

下载

立即学习go语言免费学习笔记(深入)”;

type RequestProcessor interface {
    Process(*Request) (*Response, error)
}

type Chain struct {
    handlers []RequestProcessor
}

func (c *Chain) Add(h RequestProcessor) {
    c.handlers = append(c.handlers, h)
}

func (c *Chain) Execute(req *Request) (*Response, error) {
    for _, h := range c.handlers {
        resp, err := h.Process(req)
        if err != nil || resp != nil {
            return resp, err
        }
    }
    return nil, errors.New("no handler processed the request")
}

这种结构比 HTTP 中间件更通用,但失去了 net/http 的生态兼容性。如果你只做 Web 服务,且团队熟悉 Gin/Echo,直接用框架 Use() 更安全——它已帮你封好了洋葱模型、panic 恢复、上下文透传等细节。

真正关键的不是选哪个模式,而是理解“链”的本质是函数组合 + 显式控制权移交。无论叫责任链还是中间件链,只要没搞清 next 谁来调、何时调、不调会怎样,就一定会在调试时卡在“为什么日志打了但权限没校验”这类问题上。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

180

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

393

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

191

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

273

2025.06.17

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

0

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号