职责链模式通过将请求沿处理者链条传递实现解耦,适用于多阶段验证或复杂业务逻辑。代码中定义了Handler接口和BaseHandler基础结构,构建了认证、验证、业务处理三个处理器,每个处理器可独立决定是否处理请求或转发给下一节点,最终实现灵活、可扩展的请求处理流程。

在Go语言中,职责链模式(Ch
ain of Responsibility)提供了一种将请求的发送者与接收者解耦的方式。简单来说,它允许一个请求沿着一条由多个处理者组成的链条进行传递,直到某个处理者决定处理它,或者链条的末端被抵达。这对于构建灵活、可扩展的请求处理系统特别有用,尤其是在处理复杂的业务逻辑或多阶段验证时。我个人觉得,这种模式的核心价值在于它能优雅地应对“谁来处理这个请求?”这类问题,避免了大量的条件判断嵌套。
解决方案
职责链模式的核心在于定义一个通用的处理者接口,以及每个具体处理者如何决定是处理请求还是将其传递给链中的下一个。在我看来,设计这个接口时,既要考虑处理逻辑,也要兼顾链条的连接。
我们先定义一个`Handler`接口,并实现几个具体的
处理器来模拟一个请求从认证、验证到业务处理的完整流程:
```
go
package main
import (
"fmt"
"log"
)
// Request 是我们要在链中传递的请求对象
type Request struct {
ID string
Type string
Payload string
IsAuthenticated bool
IsValidated bool
IsProcessed bool
Error error // 用于传递链条中的错误信息
}
// Handler 定义了处理请求的接口
type Handler interface {
SetNext(handler Handler)
Handle(req *Request)
}
// BaseHandler 提供了设置下一个处理者的基本实现,方便嵌入到具体处理器中
type BaseHandler struct {
next Handler
}
func (b *BaseHandler) SetNext(handler Handler) {
b.next = handler
}
// PassToNext 负责将请求传递给链中的下一个处理器
func (b *BaseHandler) PassToNext(req *Request) {
if b.next != nil {
b.next.Handle(req)
} else {
// 如果到达链的末端,但请求仍未被完全处理或存在错误,可以记录日志
if req.Error != nil {
log.Printf("请求 %s 链条结束,最终状态:失败,错误:%v", req.ID, req.Error)
} else if !req.IsProcessed {
log.Printf("请求 %s 链条结束,但未被标记为完全处理。", req.ID)
} else {
log.Printf("请求 %s 链条结束,已成功处理。", req.ID)
}
}
}
// AuthenticationHandler 模拟认证逻辑
type AuthenticationHandler struct {
BaseHandler
}
func (a *AuthenticationHandler) Handle(req *Request) {
log.Printf("认证处理器处理请求 %s...", req.ID)
if req.Error != nil { // 如果之前有错误,直接跳过当前处理
log.Printf("请求 %s 因前置错误跳过认证。", req.ID)
a.PassToNext(req) // 继续传递,让后续处理器(如日志)处理错误
return
}
if req.ID == "unauth-123" { // 模拟一个未认证的请求ID
req.Error = fmt.Errorf("请求 %s 未通过认证", req.ID)
log.Printf("请求 %s 认证失败。", req.ID)
a.PassToNext(req) // 认证失败,但将错误信息传递下去
return
}
req.IsAuthenticated = true
log.Printf("请求 %s 认证成功。", req.ID)
a.PassToNext(req)
}
// ValidationHandler 模拟数据验证逻辑
type ValidationHandler struct {
BaseHandler
}
func (v *ValidationHandler) Handle(req *Request) {
log.Printf("验证处理器处理请求 %s...", req.ID)
if req.Error != nil { // 如果之前有错误,直接跳过当前处理
log.Printf("请求 %s 因前置错误跳过验证。", req.ID)
v.PassToNext(req)
return
}
if req.Payload == "" { // 模拟一个无效的请求(空payload)
req.Error = fmt.Errorf
以上就是Golang职责链模式处理请求传递示例的详细内容,更多请关注php中文网其它相关文章!