:::tips 观察者模式又叫 发布订阅模式

:::

定义

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

示例

同步阻塞方式

golang

  1. package xtcp
  2. import (
  3. "container/list"
  4. "log"
  5. "testing"
  6. )
  7. func Test_Server(t *testing.T) {
  8. subject := ConcreteSubject{}
  9. one := ConcreteObserveOne{}
  10. two := ConcreteObserveTwo{}
  11. subject.RegisterObserver(&one)
  12. subject.RegisterObserver(&two)
  13. subject.NotifyObserver("test")
  14. subject.RemoveObserver(&one)
  15. subject.NotifyObserver("test - 2")
  16. }
  17. type Subject interface {
  18. RegisterObserver(observer Observer)
  19. RemoveObserver(observer Observer)
  20. NotifyObserver(message string)
  21. }
  22. type Observer interface {
  23. Update(message string)
  24. }
  25. type ConcreteSubject struct {
  26. observers list.List
  27. }
  28. func (c *ConcreteSubject) RegisterObserver(observer Observer) {
  29. c.observers.PushBack(observer)
  30. }
  31. func (c *ConcreteSubject) RemoveObserver(observer Observer) {
  32. for e:= c.observers.Front(); e!= nil; e = e.Next(){
  33. if e.Value == observer{
  34. c.observers.Remove(e)
  35. return
  36. }
  37. }
  38. }
  39. func (c *ConcreteSubject) NotifyObserver(message string) {
  40. for e:= c.observers.Front(); e!= nil; e = e.Next(){
  41. observer := e.Value.(Observer)
  42. observer.Update(message)
  43. }
  44. }
  45. type ConcreteObserveOne struct {
  46. }
  47. type ConcreteObserveTwo struct {
  48. }
  49. func (o *ConcreteObserveOne) Update(message string) {
  50. log.Println("one" + message)
  51. }
  52. func (o *ConcreteObserveTwo) Update(message string) {
  53. log.Println("two" + message)
  54. }

异步队列方式

:::tips 没错, 消息队列就是一种, 并且耦合更小, 因为 被观察者感知不到观察者的存在

缺点是需要引入 消息队列 中间件

:::