Go中可组合状态模式与责任链模式,使每个状态实现Handler接口成为可插拔处理器,通过Context管理状态流转,适用于多状态、行为差异大且需审计的场景。

在 Go 语言中,状态模式(State Pattern)和责任链模式(Chain of Responsibility)可以组合使用,解决“对象行为随状态变化而动态改变,且请求需按条件逐级处理”的典型场景。这种组合不是简单拼接,而是让每个状态本身成为一个可插拔的处理器节点,形成一条“带状态感知的责任链”。
核心思路是将状态抽象为符合责任链规范的处理器。定义一个通用接口,既表达“我能处理请求”,也隐含“我代表某种状态”:
// Handler 是责任链节点,也是状态的载体
type Handler interface {
Handle(ctx context.Context, req Request) (Response, error)
GetStateName() string // 便于日志、调试或决策
}
每个具体状态(如 IdleState、ProcessingState、FailedState)都实现该接口。它们内部可封装自己的数据、策略和转移逻辑,而不是被动被切换——状态自己决定是否处理、如何处理、以及是否触发状态迁移。
责任链的“传递”不依赖外部调度器,而是由当前状态处理器自主决定:
立即学习“go语言免费学习笔记(深入)”;
示例片段:
func (s *ProcessingState) Handle(ctx context.Context, req Request) (Response, error) {
// 执行实际业务逻辑
resp, err := s.doWork(ctx, req)
if err != nil {
// 失败时主动切换到 FailedState
s.ctx.SetCurrentHandler(s.failedHandler)
return Response{}, err
}
// 成功后切到 DoneState,并返回结果
s.ctx.SetCurrentHandler(s.doneHandler)
return resp, nil
}
定义一个轻量 Context 结构,持有当前 handler、状态历史、取消信号等,避免全局变量或层层传参:
type StateContext struct {
mu sync.RWMutex
current Handler
history []string
cancel func()
}
func (c *StateContext) SetCurrentHandler(h Handler) {
c.mu.Lock()
c.current = h
c.history = append(c.history, h.GetStateName())
c.mu.Unlock()
}
func (c *StateContext) Handle(ctx context.Context, req Request) (Response, error) {
c.mu.RLock()
h := c.current
c.mu.RUnlock()
if h == nil {
return Response{}, errors.New("no active state")
}
return h.Handle(ctx, req)
}
这样,业务代码只需操作 Context,完全 unaware 具体状态类型或链路结构。
这种组合适合以下情况:
避免过度设计:
不复杂但容易忽略
以上就是如何在Golang中实现状态+责任链模式_对象状态变化与请求处理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号