Skip to content

Instantly share code, notes, and snippets.

@MrHohn
Created October 2, 2016 03:40
Show Gist options
  • Save MrHohn/6e4776b450c101d5d60e3218fc4f58fc to your computer and use it in GitHub Desktop.
Save MrHohn/6e4776b450c101d5d60e3218fc4f58fc to your computer and use it in GitHub Desktop.
"Decorator Pattern in Go" learned from GopherCon 2015.
package main
import (
"fmt"
"time"
)
type Worker interface {
Do(string) bool
}
type WorkerFunc func(s string) bool
func (w WorkerFunc) Do(s string) bool {
return w(s)
}
type WorkerDecorator func(Worker) Worker
func LoggingDecorator(header string) WorkerDecorator {
return func(w Worker) Worker {
return WorkerFunc(func(s string) bool {
fmt.Printf("%s: start.\n", header)
defer fmt.Printf("%s: End.\n", header)
return w.Do(s)
})
}
}
func AuthorizationDecorator(token string) WorkerDecorator {
return func(w Worker) Worker {
return WorkerFunc(func(s string) bool {
fmt.Printf("Authorizing with token: %s\n", token)
return w.Do(s)
})
}
}
func RetryDecorator(attempts int, interval time.Duration) WorkerDecorator {
return func(w Worker) Worker {
return WorkerFunc(func(s string) (res bool) {
for i := 1; i <= attempts; i++ {
fmt.Printf("Attempt: %d.\n", i)
if res = w.Do(s); res == true {
break
}
time.Sleep(interval)
}
return res
})
}
}
func WorkerDecorate(w Worker, ds ...WorkerDecorator) Worker {
decorated := w
for _, decorator := range ds {
decorated = decorator(decorated)
}
return decorated
}
type PrintWorker struct{}
func (*PrintWorker) Do(s string) bool {
fmt.Printf("PrintWorker: Doing %s.\n", s)
return true
}
func main() {
decoratedWorker := WorkerDecorate(&PrintWorker{},
LoggingDecorator("Decorator-sample logging"),
AuthorizationDecorator("jhfaHkjfhwGquadN"),
RetryDecorator(3, 2*time.Second))
decoratedWorker.Do("some serious works")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment