在go语言中,责任链模式通过中间件实现,允许请求沿处理链传递。1. 中间件是拦截器,可在请求前后执行通用操作如日志、权限验证;2. 手动实现可通过定义handler接口并串联处理逻辑;3. 更常用的是函数式写法,中间件接收并返回http.handlerfunc,形成包裹结构;4. 使用applymiddleware按顺序组合多个中间件,顺序影响执行流程,前置逻辑按顺序执行,后置逻辑逆序执行;5. 核心思想是抽离通用逻辑,提升复用性与可维护性。

在 Golang 中,责任链(Chain of Responsibility)模式是一种行为设计模式,它允许你将请求沿着处理链传递,每个节点都有机会处理这个请求或者将其传递给下一个节点。中间件模式其实就是责任链模式的一种变体,在 Go 的 Web 框架中非常常见,比如 Gin、Echo 等框架都使用了类似机制。

下面我们就来看看如何在 Go 中实现一个责任链/中间件风格的处理流程。

中间件本质上就是一种“拦截器”:你可以在请求到达最终处理函数之前或之后做一些通用操作,比如日志记录、权限验证、限流等。
立即学习“go语言免费学习笔记(深入)”;
Go 的中间件通常是一个函数,接收一个处理函数并返回一个新的处理函数。这种结构非常适合组合多个中间件形成一条处理链。

基本形式如下:
func middleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 前置处理逻辑
log.Println("Before request")
next(w, r)
// 后置处理逻辑
log.Println("After request")
}
}这样你可以一层层包裹你的处理函数,形成一个处理链条。
如果你不依赖任何 Web 框架,也可以自己模拟一个简单的责任链结构。比如定义一个 Handler 接口:
type Handler interface {
SetNext(handler Handler)
Handle(request string)
}然后实现几个具体的 Handler:
type LoggingHandler struct {
next Handler
}
func (h *LoggingHandler) SetNext(handler Handler) {
h.next = handler
}
func (h *LoggingHandler) Handle(request string) {
fmt.Println("Logging request:", request)
if h.next != nil {
h.next.Handle(request)
}
}
type AuthHandler struct {
next Handler
}
func (h *AuthHandler) SetNext(handler Handler) {
h.next = handler
}
func (h *AuthHandler) Handle(request string) {
fmt.Println("Authenticating request:", request)
if h.next != nil {
h.next.Handle(request)
}
}使用方式如下:
handler1 := &LoggingHandler{}
handler2 := &AuthHandler{}
handler1.SetNext(handler2)
handler1.Handle("some request")这种方式虽然更贴近经典的责任链模式,但在实际开发中,尤其是在 Web 开发中,大家更倾向于使用函数式的方式组织中间件。
在 Go 的 Web 编程中,我们通常使用函数来构建中间件链。例如:
type Middleware func(http.HandlerFunc) http.HandlerFunc
然后可以写一些通用中间件:
func Logger() Middleware {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Log before request")
next(w, r)
fmt.Println("Log after request")
}
}
}
func Auth() Middleware {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user := r.Header.Get("User")
if user == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
fmt.Println("User authenticated:", user)
next(w, r)
}
}
}最后把这些中间件组合起来使用:
func applyMiddleware(h http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
for _, m := range middlewares {
h = m(h)
}
return h
}注册路由时就可以这样写:
http.HandleFunc("/api", applyMiddleware(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from API")
}, Logger(), Auth()))这样就形成了一个完整的中间件链,每个中间件都能决定是否继续执行后续逻辑。
举个例子:
applyMiddleware(handler, A(), B(), C())
调用顺序是:
理解这个顺序对调试和设计中间件非常重要。
基本上就这些。责任链和中间件的核心思想是一样的:把通用逻辑抽离出来,按需组合,提高复用性。Go 的函数式编程特性让中间件的实现既简洁又强大。只要注意中间件顺序和执行时机,就能写出清晰可维护的处理流程。
以上就是Golang中的责任链模式怎么用 中间件模式的变体实现的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号