《大话设计模式》观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式
优点

  • 解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

缺点

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
// 目标对象需实现的接口
type SubjectInterface interface {
	GetState() string
	Attach(observer interface{})
	Remove(observer interface{})
	Notify()
}

// 目标对象"父类"
type Subject struct {
	state string
	observers []interface{}
}

func (s *Subject) SetState(state string)  {
	s.state = state
}

func (s *Subject) GetState() string {
	return  s.state
}

func (s *Subject) Attach(observer interface{}) {
	s.observers = append(s.observers, observer)
}

func (s *Subject) Remove(observer interface{}) {
	for i := 0; i < len(s.observers); i++ {
		if observer.(ObserverInterface).GetName() == s.observers[i].(ObserverInterface).GetName() {
			s.observers = append(s.observers[:i], s.observers[i+1:]...)
			break
		}
	}
}

func (s *Subject) Notify() {
	for i := 0; i < len(s.observers); i++ {
		s.observers[i].(ObserverInterface).Handle()
	}
}

// 观察者需实现的接口
type ObserverInterface interface {
	GetName() string
	Handle()
}

// 观察者"父类"
type Observer struct {
	name string
	state string
	subject SubjectInterface
}

func (o *Observer) GetName() string {
	return o.name
}

func (o *Observer) SetName(name string) {
	o.name = name
}

func (o *Observer) GetState() string {
	return o.state
}

func (o *Observer) SetState(state string)  {
	o.state = state
}

func (o *Observer) GetSubjectState() string {
	return o.subject.GetState()
}

func (o *Observer) SetSubject(subject interface{}) {
	o.subject = subject.(SubjectInterface)
}

func (o *Observer) Handle(subject, subjectState, name, state string) {
	fmt.Println("Receive event: "+ subjectState +". "+
		"Calling "+ subject + " : + " + name +"'s handler : " + state)
}

// 具体观察者1
type ObserverOne struct {
	Observer
}

func (o *ObserverOne) Handle()  {
	o.SetState("Start coding")
	o.Observer.Handle("ObserverOne", o.GetSubjectState(), o.GetName(), o.GetState())
}

// 具体观察者2
type ObserverTwo struct {
	Observer
}

func (o *ObserverTwo) Handle()  {
	o.SetState("Start cooking")
	o.Observer.Handle("ObserverTwo", o.GetSubjectState(), o.GetName(), o.GetState())
}

func main() {
	var (
		subject1 SubjectOne
		observer1 ObserverOne

		subject2 SubjectTwo
		observer2 ObserverTwo
	)

	observer1.SetName("Observer 1")
	observer1.SetSubject(&subject1)
	subject1.Attach(&observer1)

	subject1.SetState("Time to code")
	subject1.Notify()

	// 取消订阅
	subject1.Remove(&observer1)
	subject1.Notify()

	observer2.SetName("Observer 2")
	observer2.SetSubject(&subject2)
	subject2.Attach(&observer2)

	subject2.SetState("Time to cook")
	subject2.Notify()
}
// 输出
// Receive event: Time to code. Calling ObserverOne : + Observer 1's handler : Start coding
// Receive event: Time to cook. Calling ObserverTwo : + Observer 2's handler : Start cooking
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值