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

基于责任链模式,按路径实现JSON到不同结构体的解码需求

解决方案:基于责任链模式实现多路径请求结构体适配

看起来你已经搭好了责任链的架子,现在需要解决不同路径对应不同请求结构体的问题,还要让createRequest组合baseRequest对吧?我给你梳理一套清晰的实现方案,直接贴代码加解释,你可以照着改:

1. 定义请求结构体(实现组合)

首先先把基础和具体请求结构体定义好,用Go的结构体嵌入实现createRequest对baseRequest的组合,这样既复用了基础字段,又能扩展特有属性:

// baseRequest 所有请求的通用基础结构体
type baseRequest struct {
    TraceID   string `json:"trace_id"`
    Timestamp int64  `json:"timestamp"`
}

// createRequest 继承(组合)baseRequest,新增创建请求的专属字段
type createRequest struct {
    baseRequest       // 嵌入baseRequest,自动拥有其所有字段
    ResourceID string `json:"resource_id"`
    Quantity   int    `json:"quantity"`
}

// cancelRequest 取消请求的结构体,同样可以嵌入baseRequest复用字段
type cancelRequest struct {
    baseRequest
    OrderID string `json:"order_id"`
}

2. 定义请求接口(实现多态)

为了让message.Request能兼容多种请求类型,我们定义一个空接口来标识所有请求结构体(也可以加通用方法,比如校验):

// Request 所有请求结构体的统一接口
type Request interface {
    // 空方法仅用于标识该类型属于请求范畴
    IsRequest()
}

// 给每个请求结构体实现接口方法
func (*baseRequest) IsRequest()    {}
func (*createRequest) IsRequest()  {}
func (*cancelRequest) IsRequest()  {}

3. 修改Message结构体

把原来的message.Request类型改成我们定义的Request接口,这样它就能容纳createRequest、cancelRequest等任意实现了接口的结构体:

// Message 责任链中传递的消息载体
type Message struct {
    Path    string  `json:"-"` // 存储请求路径,不参与JSON解码
    Request Request // 现在是接口类型,支持多态
    // 其他原有字段...
}

4. 实现请求工厂Handler

在责任链中新增一个请求工厂Handler,它的职责就是根据请求路径创建对应类型的空结构体指针,传给后续的jsonReader()解码:

// RequestFactoryHandler 责任链中负责创建对应请求结构体的处理器
type RequestFactoryHandler struct {
    next Handler // 责任链下一个处理器
}

func NewRequestFactoryHandler(next Handler) *RequestFactoryHandler {
    return &RequestFactoryHandler{next: next}
}

func (h *RequestFactoryHandler) Handle(msg *Message) error {
    // 根据路径匹配,创建对应空请求指针
    switch msg.Path {
    case "/create":
        msg.Request = &createRequest{}
    case "/cancel":
        msg.Request = &cancelRequest{}
    default:
        return fmt.Errorf("unsupported request path: %s", msg.Path)
    }

    // 传递给下一个处理器(比如你的jsonReader所在的handler)
    if h.next != nil {
        return h.next.Handle(msg)
    }
    return nil
}

5. 适配jsonReader()

现在你的jsonReader()可以直接用msg.Request进行解码了,因为它已经是对应类型的指针,Unmarshal会自动把JSON数据解析到正确的结构体里:

// jsonReader 从请求体解码JSON到对应的请求结构体
func jsonReader(msg *Message, requestBody []byte) error {
    return json.Unmarshal(requestBody, msg.Request)
}

关键点说明

  • 用结构体嵌入实现组合,比继承更灵活,符合Go的设计哲学;
  • 用接口类型实现多态,让Message能兼容多种请求类型,不需要修改原有责任链的核心逻辑;
  • 请求工厂Handler作为责任链的第一个节点,提前创建好对应结构体,后续处理器只需要专注于解码和业务逻辑,职责单一。

内容的提问来源于stack exchange,提问作者zerozero7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:19:47