Degorator implements the decorator pattern in Golang. This can be used to add behavior, such as logs or metrics, into a function without affecting the original behavior at runtime.
##Requirements
go get github.com/starwander/degorator
- Decorate: injects two functions(injectedBefore & injectedAfter) into the target function.
- MakeDecorator: generate a decorator to a certain function type which can be used later.
Original | Decorated |
---|---|
func Myfunc(in)out{ | func MyfuncDecorated(in)out{ |
...... | injectedBefore(in) |
do someting | out = MyFunc(in) |
...... | injectedAfter(out,in) |
} | } |
package main
import (
"fmt"
"github.com/starwander/degorator"
)
type Counter struct {
number int
error int
}
func (m *Counter) add(s string) {
if s == "nothing" {
return
}
m.number++
}
func (m *Counter) addErr(err error) {
if err != nil {
m.error++
}
}
func Log(s string) {
fmt.Println("input:", s)
}
type MyFunc func(s string) error
var myFunc MyFunc = func(s string) error {
if s == "error" {
return fmt.Errorf("error")
}
return nil
}
func main() {
counter := new(Counter)
var CounterDecorator func(MyFunc) MyFunc
err := degorator.MakeDecorator(&CounterDecorator, counter.add, counter.addErr)
if err != nil {
panic(err)
}
myFunc = CounterDecorator(myFunc)
myFunc("something")
//1 0
fmt.Println(counter.number, counter.error)
myFunc("error")
//2 1
fmt.Println(counter.number, counter.error)
myFunc("nothing")
//2 1
fmt.Println(counter.number, counter.error)
var myFuncDecorated MyFunc
err = degorator.Decorate(&myFuncDecorated, myFunc, Log, nil)
if err != nil {
panic(err)
}
//input: another
myFuncDecorated("another")
//3 1
fmt.Println(counter.number, counter.error)
}
Degorator source code is licensed under the Apache Licence, Version 2.0.