设计模式:观察者模式解析与Go语言实现

88 阅读2分钟

1. 引言

观察者模式(Observer Pattern)是软件设计模式中的一种行为型模式,它定义了对象之间的一对多依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。

DALL·E 2023-11-19 10.22.00 - A conceptual illustration for the Observer design pattern in software engineering. The image should depict a central object (the 'Subject') with multi.png

2. 观察者模式的结构

观察者模式主要包含两类对象:

  • 主题(Subject):它维护一组观察者,提供用于增加和移除观察者的方法。
  • 观察者(Observer):为那些在主题状态发生改变时需获得通知的对象提供一个更新接口。

3. Go语言实现示例

以下是使用Go语言实现观察者模式的示例:

package main

import "fmt"

// 观察者接口
type Observer interface {
	Update(*Subject)
}

// 主题
type Subject struct {
	observers []Observer
	state     int
}

func NewSubject() *Subject {
	return &Subject{observers: make([]Observer, 0)}
}

func (s *Subject) Attach(o Observer) {
	s.observers = append(s.observers, o)
}

func (s *Subject) Detach(o Observer) {
	for i, observer := range s.observers {
		if observer == o {
			s.observers = append(s.observers[:i], s.observers[i+1:]...)
			break
		}
	}
}

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

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

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

// 具体观察者
type ConcreteObserver struct {
	id int
}

func NewConcreteObserver(id int) *ConcreteObserver {
	return &ConcreteObserver{id: id}
}

func (c *ConcreteObserver) Update(s *Subject) {
	fmt.Printf("Observer %d: Subject's state changed to %d\n", c.id, s.GetState())
}

func main() {
	subject := NewSubject()

	observer1 := NewConcreteObserver(1)
	subject.Attach(observer1)

	observer2 := NewConcreteObserver(2)
	subject.Attach(observer2)

	subject.SetState(10)
	subject.Detach(observer1)
	subject.SetState(20)
}

4. 观察者模式的应用场景

观察者模式适用于以下场景:

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中可以让它们各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。

5. 观察者模式的优缺点

优点

  • 支持简单的广播通信。
  • 观察者和主题之间的抽象耦合最小。

缺点

  • 如果一个被观察的主题对象有很多直接和间接的观察者的话,通知每一个观察者都是耗时的。

6. 结语

观察者模式是一种有效的方式来实现事件处理系统,它使得多个对象能够观察一个对象的状态变化,从而实现松耦合。