Go语言含反射调用的ProcessRequest方法复用重构方案咨询
可行重构方案
方案1:提取通用反射处理函数
把反射调用的核心逻辑抽成独立函数,让A、B的ProcessRequest直接调用它,彻底避免重复代码:
import "reflect" import "fmt" // 通用反射调用函数,接收目标实例和要调用的方法名 func processRequest(target interface{}, methodName string) error { val := reflect.ValueOf(target) // 处理指针类型的目标实例 if val.Kind() == reflect.Ptr { val = val.Elem() } method := val.MethodByName(methodName) if !method.IsValid() { return fmt.Errorf("method %s not found", methodName) } // 调用方法(如需传递参数可修改Call的参数) results := method.Call(nil) // 处理方法返回的错误(如果有的话) if len(results) > 0 { if err, ok := results[0].Interface().(error); ok { return err } } return nil } // 结构体A的ProcessRequest func (a *A) ProcessRequest() error { return processRequest(a, "SomeFunc") } // 结构体B的ProcessRequest func (b *B) ProcessRequest() error { return processRequest(b, "AnotherFunc") }
方案2:组合绑定目标实例的ProcessProvider
放弃嵌入,改为让ProcessProvider持有目标实例和方法名,通过构造函数完成绑定,解决接收者不匹配的问题:
import "reflect" import "fmt" type ProcessProvider struct { target interface{} methodName string } func (p *ProcessProvider) ProcessRequest() error { val := reflect.ValueOf(p.target) if val.Kind() == reflect.Ptr { val = val.Elem() } method := val.MethodByName(p.methodName) if !method.IsValid() { return fmt.Errorf("method %s not found", p.methodName) } results := method.Call(nil) if len(results) > 0 { if err, ok := results[0].Interface().(error); ok { return err } } return nil } // 结构体A type A struct { ProcessProvider } func NewA() *A { a := &A{} // 绑定自身实例和要调用的方法名 a.ProcessProvider = ProcessProvider{target: a, methodName: "SomeFunc"} return a } func (a *A) SomeFunc() { // 原有业务逻辑 } // 结构体B type B struct { ProcessProvider } func NewB() *B { b := &B{} b.ProcessProvider = ProcessProvider{target: b, methodName: "AnotherFunc"} return b } func (b *B) AnotherFunc() { // 原有业务逻辑 }
方案3:代码生成(适合大量同类结构体场景)
如果后续还有更多结构体需要实现ProcessRequest,可以用Go的go generate工具自动生成代码,避免手动重复编写:
- 先定义基础结构体和方法:
//go:generate go run gen_process.go package yourpackage type A struct{} func (a *A) SomeFunc() {} type B struct{} func (b *B) AnotherFunc() {}
- 编写代码生成工具
gen_process.go,根据模板生成对应结构体的ProcessRequest方法,新增结构体时只需修改配置或模板即可。
内容的提问来源于stack exchange,提问作者Evilolipop
相关产品推荐
相关产品推荐

