DesignPatternOberver观察者模式

DesignPatternOberver观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

标准定义

UML图

观察者模式包含四个角色

  • Subject(抽象目标):又称为主题,是被观察的对象
  • ConcreteSubject(具体目标):抽象目标的子类,通常包含有经常发生改变的数据,当它的状态发生改变时,向其各个观察者发出通知
  • Observer(抽象观察者):观察者将对观察目标的改变做出反应
  • ConcreteObserver(具体观察者):具体观察者中维持一个指向具体目标对象的引用,它用于存储具体观察者的有关状态,这些状态和具体目标的状态保持一致

实际案例

场景模拟

爱玩联盟,之前还了解过联盟一点点的背景故事。符文大陆的国家艾欧尼亚很垃圾,诺克萨斯牛逼,就要干艾欧尼亚。首先,打仗,莽之前要观察对面的国家状态,他们牛逼还打啥了。选中他们最弱的时候干

UML图

代码实现

package my

import "fmt"

type Subject interface {
	Attach()           // 添加观察者们
	Notify(o Observer) // 通知观察者
}

type Ionia struct {
	Name      string
	Observers []Observer // 一直默默注视他的人
	State     bool       // 自己的状态 true: 表示自己状态很好,不能被攻击
}

func NewIonia() *Ionia {
	return &Ionia{
		Name:      "艾欧尼亚",
		Observers: make([]Observer, 0),
		State:     true,
	}
}

func (i *Ionia) SetState(b bool) {
	i.State = b
}

func (i *Ionia) GetState() bool {
	return i.State
}

func (i *Ionia) Attach(o Observer) {
	i.Observers = append(i.Observers, o)
}

func (i *Ionia) Notify() {
	for _, observer := range i.Observers {
		if i.State {
			fmt.Println("艾欧尼亚现在牛逼不能进攻")
			continue
		}

		observer.Update()
	}
}

type Observer interface {
	Update() // 根据情报做出相应的动作
}

type Noxus struct {
	Name string
}

func NewNoxus() *Noxus {
	return &Noxus{Name: "诺克萨斯"}
}

func (n *Noxus) Update() {
	fmt.Println("攻打艾欧尼亚")
}

func TTmain() {
	ionia := NewIonia()
	noxus := NewNoxus()

	ionia.Attach(noxus)

	for i := 0; i <= 5; i++ {
		if i%2 == 0 {
			ionia.SetState(false)
		} else {
			ionia.SetState(true)
		}

		ionia.Notify()
	}
}


# 测试ttmain()输出
攻打艾欧尼亚
艾欧尼亚现在牛逼不能进攻
攻打艾欧尼亚
艾欧尼亚现在牛逼不能进攻
攻打艾欧尼亚
艾欧尼亚现在牛逼不能进攻

业务拓展

场景模拟

如果是这样的话,太简单了。再来个场景: 诺克萨斯之前的罪过恕瑞玛。当诺克萨斯干别人时候,自己也是最空虚的时候。这时候就干他

核心点+疑难杂症

  • 这时候,诺克萨斯变成了观察者,同时也变成了被观察者
  • 所以,对线创建问题就出现了
  • 还有接口就是一团,全部融合进去,既是观察者优势Subject,显然是不适用的
posted @ 2020-12-12 19:52  maob  阅读(73)  评论(0编辑  收藏  举报