Skip to content

Latest commit

 

History

History
144 lines (101 loc) · 4.91 KB

设计模式-观察者模式.md

File metadata and controls

144 lines (101 loc) · 4.91 KB

观察者模式

概念

  • 观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。
  • 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。
  • 观察者模式属于行为型模式。

目的

  • 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
  • 在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。

解决的问题

  • 一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
  • 此种模式通常被用来实现事件处理系统。

角色

  • 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
  • 具体主题(Concrete Subject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
  • 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
  • 具体观察者(Concrete Observer):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

优点

  • 观察者和被观察者是抽象耦合的,观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。
  • 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。

缺点

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

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象...,可以使用观察者模式创建一种链式触发机制。

UML图

UML

实现

定义抽象观察者

type Observer interface {
    Update()
}

定义抽象主题

type Subject interface {
    GetState() int
    SetState(int)
    Attach(Observer)
    Notify()
}

定义具体观察者

type FirstObserver struct {
    subject Subject
}

func NewFirstObserver(subject Subject) *FirstObserver {
    observer := &FirstObserver{subject: subject}
    subject.Attach(observer)
    return observer
}
func (observer *FirstObserver) Update() {
    fmt.Printf("this is the first observer , state from Subject is %d\n", observer.subject.GetState())
}

定义具体主题

type ConcreteSubject struct {
    observers []Observer
    state     int
}

func (subject *ConcreteSubject) GetState() int {
    return subject.state
}

func (subject *ConcreteSubject) SetState(state int) {
    subject.state = state
    subject.Notify()
}

func (subject *ConcreteSubject) Attach(observer Observer) {
    subject.observers = append(subject.observers, observer)
}

func (subject *ConcreteSubject) Notify() {
    for _, observer := range subject.observers {
        observer.Update()
    }
}

编写测试类

func TestConcreteSubject_Notify(t *testing.T) {
    subject := &ConcreteSubject{}
    first := NewFirstObserver(subject)
    second := NewSecondObserver(subject)
    
    subject.SetState(8)
    
    fmt.Println("after notify")
    first.Update()
    second.Update()
}

思维导图

图片版

设计模式-观察者模式-思维导图.jpg

pdf

设计模式-观察者模式-思维导图.pdf

在线查看

设计模式-观察者模式-思维导图.html