You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

命令模式实现疑问:执行失败重试计数与日志记录方案咨询

命令模式下带重试计数的解决方案

核心思路:用装饰器模式扩展命令的重试计数能力,遵循SOLID原则

无需修改原有Command接口和实现,通过包装类添加重试计数功能,既满足开闭原则,又保持单一职责。


  1. 保持原有Command接口不变
type Command interface {
    Execute() error
}
  1. 实现重试装饰器类
    该类包装原Command实例,负责记录重试次数,并转发执行逻辑:
type RetryCommand struct {
    cmd        Command
    retryCount int
    maxRetries int
}

// 构造函数:传入原命令和最大重试次数
func NewRetryCommand(cmd Command, maxRetries int) *RetryCommand {
    return &RetryCommand{
        cmd:        cmd,
        maxRetries: maxRetries,
        retryCount: 0,
    }
}

// 转发执行逻辑,失败时递增重试计数
func (r *RetryCommand) Execute() error {
    err := r.cmd.Execute()
    if err != nil {
        r.retryCount++
    }
    return err
}

// 获取当前已重试次数
func (r *RetryCommand) RetryCount() int {
    return r.retryCount
}

// 获取允许的最大重试次数
func (r *RetryCommand) MaxRetries() int {
    return r.maxRetries
}
  1. 修改队列处理逻辑
    取出命令后,先检查是否已被包装,未包装则初始化重试装饰器;执行失败后根据计数判断重试或记录日志:
cmd := queue.Take()

// 适配未包装的原始命令
retryCmd, isRetryCmd := cmd.(*RetryCommand)
if !isRetryCmd {
    retryCmd = NewRetryCommand(cmd, 2) // 设置最大重试2次
}

err := retryCmd.Execute()
if err != nil {
    if retryCmd.RetryCount() <= retryCmd.MaxRetries() {
        // 未达重试上限,重新入队
        queue.Add(retryCmd)
    } else {
        // 超过重试次数,记录错误日志
        log.Printf("命令执行失败,已耗尽最大重试次数(%d次),错误信息:%v", retryCmd.MaxRetries(), err)
    }
}

SOLID原则契合点

  • 开闭原则:原有Command的实现无需修改,通过装饰器扩展重试功能
  • 单一职责:原Command专注业务逻辑,RetryCommand仅负责重试计数与执行转发
  • 依赖倒置:队列处理逻辑依赖Command抽象,而非具体实现,可灵活替换命令类型

内容的提问来源于stack exchange,提问作者Илья Харламов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:40:55