观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
优点:
- 解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。
缺点:
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
// 目标对象需实现的接口
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