Open1

デザインパターン

shoetshoet

オブザーバーパターン

  • Subscriber①にロガーオブジェクト
  • Subscriber②にどこかに表示するオブジェクト
    を設定
package main

import (
	"fmt"
	"io"
	"os"
)

type Subscriber interface {
	Notify(data string)
}

// Subscriber 1
type Logger struct {
	writer io.Writer
}

func NewLogger(w io.Writer) *Logger {
	return &Logger{
		writer: w,
	}
}

func (l *Logger) Notify(data string) {
	fmt.Fprintf(l.writer, "by logger: %s\n", data)
}

// Subscriber 2
type Display struct {
	writer io.Writer
}

func NewDisplay(w io.Writer) *Display {
	return &Display{
		writer: w,
	}
}

func (d *Display) Notify(data string) {
	fmt.Fprintf(d.writer, "by display: %s\n", data)
}

// Observer
type Observer struct {
	subscribers []Subscriber
}

func (o *Observer) PushSubscriber(s Subscriber) {
	o.subscribers = append(o.subscribers, s)
}

func (o *Observer) Notify(data string) {
	for _, s := range o.subscribers {
		s.Notify(data)
	}
}

func main() {
	f, err := os.Create("test.log")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer f.Close()

	logger := NewLogger(f)
	display := NewDisplay(os.Stdout)

	observer := Observer{}
	observer.PushSubscriber(logger)
	observer.PushSubscriber(display)

	observer.Notify("hoge")
}