美文网首页
设计模式——观察者模式

设计模式——观察者模式

作者: DevilRoshan | 来源:发表于2020-11-07 19:07 被阅读0次

    什么是观察者模式?

    又叫发布-订阅模式(Publish/Subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

    实现

    // 事件
    type Event struct {
        Data int
    }
    
    type Observer interface {
        NotifyCallback(event Event)
    }
    
    type Subject interface {
        AddListener(observer Observer)
        RemoveListener(observer Observer)
        Notify(event Event)
    }
    
    type EventObserver struct {
        ID   int
        Time time.Time
    }
    
    type EventSubject struct {
        Observers sync.Map
    }
    
    func (this EventObserver) NotifyCallback(event Event) {
        fmt.Printf("Received:%d after %v\n", event.Data, time.Since(this.Time))
    }
    
    func (this *EventSubject) AddListener(observer Observer) {
        this.Observers.Store(observer, struct{}{})
    }
    
    func (this *EventSubject) RemoveListener(observer Observer) {
        this.Observers.Delete(observer)
    }
    
    func (this *EventSubject) Notify(event Event) {
        this.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 = i+j, i {
                out <- i
            }
        }()
        return out
    }
    
    func TestFib(t *testing.T) {
        //for x := range Fib(10) {
        //  fmt.Println(x)
        //}
    
        event := EventSubject{Observers:sync.Map{}}
        obs1 := EventObserver{ID:1, Time:time.Now()}
        obs2 := EventObserver{ID:2, Time:time.Now()}
    
        event.AddListener(obs1)
        event.AddListener(obs2)
        event.RemoveListener(obs1)
    
        for x:= range Fib(10) {
            event.Notify(Event{Data:x})
        }
    }
    /*
    === RUN   TestFib
    Received:0 after 0s
    Received:1 after 0s
    Received:1 after 0s
    Received:2 after 0s
    Received:3 after 0s
    Received:5 after 0s
    Received:8 after 0s
    --- PASS: TestFib (0.00s)
    PASS
    */
    

    优点

    • 观察者和被观察者是抽象耦合的;
    • 建立了一套触发机制;

    缺点

    • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;

    • 如果观察者和观察目标间有循环依赖,可能导致系统崩溃;

    • 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的。

    使用场景

    • 关联行为场景;
    • 事件多级触发场景;
    • 跨系统的消息变换场景,如消息队列的处理机制。

    注意

    • 避免循环引用;
    • 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

    相关文章

      网友评论

          本文标题:设计模式——观察者模式

          本文链接:https://www.haomeiwen.com/subject/cnrpvktx.html