Skip to content

Instantly share code, notes, and snippets.

@rnkoaa
Last active September 15, 2020 16:38
Show Gist options
  • Save rnkoaa/2e79bb059e2a174be6466ceb65e30d32 to your computer and use it in GitHub Desktop.
Save rnkoaa/2e79bb059e2a174be6466ceb65e30d32 to your computer and use it in GitHub Desktop.
Golang Interfaces and Dependency Injection
package main
import (
"encoding/json"
"fmt"
"os"
)
type NotificationState int
const (
Error NotificationState = iota
Info
Unknown
)
type Notification struct {
State NotificationState `json:"state"`
Message string `json:"message"`
}
type Notifier interface {
Notify(notification Notification) error
}
type SlackNotifier struct{}
func NewSlackNotifier() *SlackNotifier {
return &SlackNotifier{}
}
type EmailNotifier struct{}
func NewEmailNotifier() *EmailNotifier {
return &EmailNotifier{}
}
func (e EmailNotifier) Notify(notification Notification) error {
b, err := json.Marshal(notification)
if err != nil {
return err
}
fmt.Printf("Sending Email Notification %s\n", b)
return nil
}
func (s SlackNotifier) Notify(notification Notification) error {
b, err := json.Marshal(notification)
if err != nil {
return err
}
fmt.Printf("Sending Slack Notification %s\n", b)
return nil
}
type App struct {
Notifiers []Notifier
}
func NewApp(notifiers ...Notifier) *App {
return &App{
Notifiers: notifiers,
}
}
func (a *App) WithNotifier(notifier Notifier) *App {
if a.Notifiers == nil {
a.Notifiers = make([]Notifier, 0)
}
a.Notifiers = append(a.Notifiers, notifier)
return a
}
func (a *App) SendNotification(message string, state int) error {
notification := Notification{
Message: message,
}
if state == 0 {
notification.State = Error
} else {
notification.State = Info
}
errs := make([]error, 0)
for _, n := range a.Notifiers {
err := n.Notify(notification)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return fmt.Errorf("too many errors sending notifications")
}
return nil
}
func main() {
notifier := NewSlackNotifier()
emailNotifier := NewEmailNotifier()
app := NewApp(notifier)
app = app.WithNotifier(emailNotifier)
err := app.SendNotification("message from app", 1)
if err != nil {
fmt.Printf("error sending email notification: %v\n", err)
os.Exit(1)
}
fmt.Println("Done.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment