观察者模式

2019-02-01  本文已影响0人  bocsoft

观察者模式的定义:
  在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。

抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。

package observer

import "math/rand"

/*
观察者模式的定义:
  在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
    其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。

抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。

 */
type number interface {
    getNumber() int
}

//观察者接口
type observer interface {
    update() int
}

//主题
type numberGenerator struct {
    observers []observer
}

//增加观察者
func (self *numberGenerator) AddObserver(observer observer) {
    self.observers = append(self.observers, observer)
}
//通知观察者
func (self *numberGenerator) notifyObservers() []int {
    var result []int
    for _, observer := range self.observers {
        result = append(result, observer.update())
    }
    return result
}

//具体主题
type randomNumberGenerator struct {
    *numberGenerator
}

func NewRandomNumberGenerator() *randomNumberGenerator {
    return &randomNumberGenerator{&numberGenerator{}}
}

//实现Number接口
func (self *randomNumberGenerator) getNumber() int {
    return rand.Intn(50)
}

//具体主题进行通知
func (self *randomNumberGenerator) Execute() []int {
    return self.notifyObservers()
}


//具体观察者
type DigitObserver struct {
    generator number
}

func (self *DigitObserver) update() int {
    return self.generator.getNumber()
}


package observer

import "testing"

func TestObserver(t *testing.T) {
    //定义主题
    random := NewRandomNumberGenerator()

    //定义观察者
    o1 := &DigitObserver{random}
    o2 := &DigitObserver{random}

    random.AddObserver(o1)
    random.AddObserver(o2)

    //通过具体主题进行通知
    result := random.Execute()

    for _, r := range result {
        if len(result) != 2 && r > 50 {
            t.Errorf("Expect result to equal random int array")
        }
    }
}



上一篇 下一篇

猜你喜欢

热点阅读