Created
October 2, 2016 03:40
-
-
Save MrHohn/6e4776b450c101d5d60e3218fc4f58fc to your computer and use it in GitHub Desktop.
"Decorator Pattern in Go" learned from GopherCon 2015.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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