跳到主要内容

装饰器模式

泛型修饰器 左耳朵耗子在他的Go语言的修饰器编程一文中通过反射的方式,提供了类泛型的修饰器方式:

func Decorator(decoPtr, fn interface{}) (err error) {
var decoratedFunc, targetFunc reflect.Value

decoratedFunc = reflect.ValueOf(decoPtr).Elem()
targetFunc = reflect.ValueOf(fn)

v := reflect.MakeFunc(targetFunc.Type(),
func(in []reflect.Value) (out []reflect.Value) {
fmt.Println("before")
out = targetFunc.Call(in)
fmt.Println("after")
return
})

decoratedFunc.Set(v)
return
}

stackoverflow也有一篇问答提供了反射实现类泛型的装饰器模式,基本都是类似的。

func Decorate(impl interface{}) interface{} {
fn := reflect.ValueOf(impl)
//What does inner do ? What is this codeblock ?
inner := func(in []reflect.Value) []reflect.Value { //Why does this return the same type as the parameters passed to the function ? Does this mean this decorator only works for fns with signature func (arg TypeA) TypeA and not func (arg TypeA) TypeB ?
f := reflect.ValueOf(impl)
fmt.Println("Stuff before")
// ...
ret := f.Call(in) //What does call do ? Why cant we just use f(in) ?
fmt.Println("Stuff after")
// ...
return ret
}
v := reflect.MakeFunc(fn.Type(), inner)
return v.Interface()
}

当然最早14年的时候saelo就提供了这个gist,居然是零star,零fork,我贡献一个fork。