1. オブザーバーパターンとは

オブザーバーパターンは、オブジェクト間の1対多の依存関係を確立するために使用される行動デザインパターンです。具体的には、オブジェクト(サブジェクトまたは観測可能と呼ばれます)が変更されると、そのすべての依存関係(観測者と呼ばれます)が自動的に通知および更新されます。このパターンにより、サブジェクトと観測者の間で緩やかな結合が可能となり、オブジェクト間の非結合性と柔軟性が実現されます。

2. オブザーバーパターンの特性と利点

オブザーバーパターンには以下の特性と利点があります:

  • サブジェクトと観測者の間で緩やかな結合が可能であり、サブジェクトは観測者の具体的な実装の詳細を知る必要はありません。
  • 観測者の動的な追加と削除が可能であり、システムが柔軟性を持ちます。
  • サブジェクトと観測者の間でオープンクローズドの原則に従い、独立した拡張と再利用が可能です。
  • サブジェクトが複数の観測者を持つ1対多の依存関係を確立できます。

3. オブザーバーパターンの実用例

オブザーバーパターンは、GUIインタフェースにおけるイベント処理メカニズム、株式市況のリアルタイムな情報提供、eコマースプラットフォームにおけるプロモーション活動の通知など、現実のさまざまな場面で実用されています。

4. Golangにおけるオブザーバーパターンの実装

4.1 UMLクラス図

Observer Pattern in Golang

4.2 例の紹介

この例では、サブジェクト(Subject)と2つの観測者(ObserverAとObserverB)があります。サブジェクトは観測者を登録、削除、通知することができます。

4.3 実装手順

4.3.1 サブジェクトインタフェースと具象サブジェクトクラスの作成

type Subject interface {
    RegisterObserver(observer Observer)
    RemoveObserver(observer Observer)
    NotifyObservers()
}

type ConcreteSubject struct {
    observers []Observer
}

// リスナーオブジェクトの登録
func (subject *ConcreteSubject) RegisterObserver(observer Observer) {
    subject.observers = append(subject.observers, observer)
}

// リスナーオブジェクトの削除
func (subject *ConcreteSubject) RemoveObserver(observer Observer) {
    for i, obs := range subject.observers {
        if obs == observer {
            subject.observers = append(subject.observers[:i], subject.observers[i+1:]...)
            break
        }
    }
}

// イベント通知のトリガー
func (subject *ConcreteSubject) NotifyObservers() {
    for _, observer := range subject.observers {
        observer.Update()
    }
}

4.3.2 観測者インタフェースと具象観測者クラスの作成

type Observer interface {
    Update()
}

type ConcreteObserverA struct {}

func (observer *ConcreteObserverA) Update() {
    fmt.Println("Observer A が通知されました。")
}

type ConcreteObserverB struct {}

func (observer *ConcreteObserverB) Update() {
    fmt.Println("Observer B が通知されました。")
}

4.4 例のコードデモ

func main() {
    subject := &ConcreteSubject{}
    observerA := &ConcreteObserverA{}
    observerB := &ConcreteObserverB{}

    subject.RegisterObserver(observerA)
    subject.RegisterObserver(observerB)

    subject.NotifyObservers()

    subject.RemoveObserver(observerA)

    subject.NotifyObservers()
}

出力:

Observer A が通知されました。
Observer B が通知されました。
Observer B が通知されました。

上記の例のコードは、オブザーバーパターンの具体的な実装を示しています。サブジェクト(ConcreteSubject)が2つの観測者(ObserverAとObserverB)を登録し、それからこれらの2つの観測者に通知しました。その後、観測者Aはサブジェクトから解除され、残っている観測者Bに再度通知されました。