Skip to content

Commit 00ffbfa

Browse files
committed
add reflect decorator
1 parent 4431adb commit 00ffbfa

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

design/decorator/decorator_func.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package decorator
22

33
import (
4+
"fmt"
45
"net/http"
6+
"reflect"
57
)
68

79
// 方法的装饰器模式, 包装某个方法
@@ -21,3 +23,33 @@ func Auth(h http.HandlerFunc) http.HandlerFunc {
2123
func f(w http.ResponseWriter, r *http.Request) {
2224
w.Write([]byte("Hello World"))
2325
}
26+
27+
// 用 reflection 机制写的一个比较通用的修饰器
28+
// https://coolshell.cn/articles/17929.html
29+
func Decorator(decoPtr, fn interface{}) (err error) {
30+
var decoratedFunc, targetFunc reflect.Value
31+
32+
decoratedFunc = reflect.ValueOf(decoPtr).Elem()
33+
targetFunc = reflect.ValueOf(fn)
34+
35+
v := reflect.MakeFunc(targetFunc.Type(),
36+
func(in []reflect.Value) (out []reflect.Value) {
37+
fmt.Println("before")
38+
out = targetFunc.Call(in)
39+
fmt.Println("after")
40+
return
41+
})
42+
43+
decoratedFunc.Set(v)
44+
return
45+
}
46+
47+
func foo(a, b, c int) int {
48+
fmt.Printf("%d, %d, %d \n", a, b, c)
49+
return a + b + c
50+
}
51+
52+
func bar(a, b string) string {
53+
fmt.Printf("%s, %s \n", a, b)
54+
return a + b
55+
}

design/decorator/decorator_func_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,14 @@ func TestAuth(t *testing.T) {
1616
t.Error(err)
1717
}
1818
}
19+
20+
func TestReflectDecorator(t *testing.T) {
21+
type MyFoo func(int, int, int) int
22+
var myfoo MyFoo
23+
Decorator(&myfoo, foo)
24+
myfoo(1, 2, 3)
25+
26+
mybar := bar
27+
Decorator(&mybar, bar)
28+
mybar("hello", "world!")
29+
}

0 commit comments

Comments
 (0)