Golang设计模式——23观察者模式

观察者模式

定义

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

优点

  1. 解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。
  2. 建立一套触发机制。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  2. 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

场景

  1. 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
  2. 事件多级触发场景。
  3. 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

代码

在这里插入图片描述

package Observer

import (
	"fmt"
	"sync"
	"time"
)

type Event struct {
	Data int
}

type Observer interface {
	NotifyCallBack(event Event)
}

type Subject interface {
	AddListener(observer Observer)
	RemoveListener(observer Observer)
	Notify(event Event)
}

type ConcreteObserver struct {
	ID   int
	Time time.Time
}

type ConcreteSubject struct {
	Observers sync.Map
}

func (e *ConcreteObserver) NotifyCallBack(event Event) {
	fmt.Println(fmt.Sprintf("Recieved:%d after %v\n", event.Data, time.Since(e.Time)))
}

func (e *ConcreteSubject) AddListener(obs Observer) {
	e.Observers.Store(obs, struct{}{})
}

func (e *ConcreteSubject) RemoveListener(obs Observer) {
	e.Observers.Delete(obs)
}

func (e *ConcreteSubject) Notify(event Event) {
	e.Observers.Range(func(key, value interface{}) bool {
		if key == nil {
			return false
		}
		key.(Observer).NotifyCallBack(event)
		return true
	})
}

func Fib(n int) chan int {
	out := make(chan int)
	go func() {
		defer close(out)
		for i, j := 0, 1; i < n; i, j = j, i+j {
			out <- i
		}
	}()
	return out
}

package Observer

import (
	"sync"
	"testing"
	"time"
)

func TestFib(t *testing.T) {
	n := ConcreteSubject{Observers: sync.Map{}}
	obs1 := ConcreteObserver{
		ID:   1,
		Time: time.Now(),
	}
	obs2 := ConcreteObserver{
		ID:   1,
		Time: time.Now(),
	}
	n.AddListener(&obs1)
	n.AddListener(&obs2)
	for x := range Fib(10) {
		n.Notify(Event{Data: x})
	}
}

其他设计模式

设计模式Git源代码
00简单工厂模式
01工厂方法模式
02抽象工厂模式
03外观模式
04建造者模式
05桥接模式
06命令模式
07迭代器模式
08模板模式
09访问者模式
10备忘录模式
11责任链模式
12中介模式
13原型模式
14状态模式
15策略模式
16享元模式
17组合模式
18解释器模式
19单例模式
20适配器模式
21代理模式
22装饰器模式
23观察者模式

posted @ 2021-09-26 15:12  cheems~  阅读(150)  评论(0编辑  收藏  举报