Subject.ts

// Subject.ts - 观察者模式核心类

export type Observer<T = any> = (data: T) => void

/**
 * 被观察者(主题)
 * 观察者模式:一对多依赖关系,当主题状态变化时通知所有观察者
 */
export class Subject<T = any> {
  private observers = new Set<Observer<T>>()
  private state: T | undefined

  /**
   * 添加观察者
   */
  attach(observer: Observer<T>): void {
    this.observers.add(observer)
    // 如果已有状态,立即通知新观察者
    if (this.state !== undefined) {
      observer(this.state)
    }
  }

  /**
   * 移除观察者
   */
  detach(observer: Observer<T>): void {
    this.observers.delete(observer)
  }

  /**
   * 通知所有观察者
   */
  notify(data: T): void {
    this.state = data
    this.observers.forEach((observer) => observer(data))
  }

  /**
   * 获取当前状态
   */
  getState(): T | undefined {
    return this.state
  }

  /**
   * 清除状态并通知观察者
   */
  clear(): void {
    this.state = undefined
    this.observers.forEach((observer) => observer(undefined as T))
  }

  /**
   * 获取观察者数量
   */
  get observerCount(): number {
    return this.observers.size
  }
}

/**
 * 多主题管理器
 * 管理多个命名的 Subject
 */
export class SubjectManager {
  private subjects = new Map<string, Subject<any>>()

  private ensureSubject<T>(key: string): Subject<T> {
    if (!this.subjects.has(key)) {
      this.subjects.set(key, new Subject<T>())
    }
    return this.subjects.get(key)!
  }

  /**
   * 获取指定 key 的 Subject(高级/更原生的观察者用法)
   */
  subject<T>(key: string): Subject<T> {
    return this.ensureSubject<T>(key)
  }

  /**
   * 订阅指定主题
   */
  subscribe<T>(key: string, observer: Observer<T>): void {
    this.ensureSubject<T>(key).attach(observer)
  }

  /**
   * 取消订阅
   */
  unsubscribe<T>(key: string, observer: Observer<T>): void {
    this.ensureSubject<T>(key).detach(observer)
  }

  /**
   * 发布数据
   */
  publish<T>(key: string, data: T): void {
    this.ensureSubject<T>(key).notify(data)
  }

  /**
   * 获取当前数据
   */
  getData<T>(key: string): T | undefined {
    return this.ensureSubject<T>(key).getState()
  }

  /**
   * 清除数据
   */
  clearData(key: string): void {
    this.ensureSubject(key).clear()
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
上次更新:
(adsbygoogle = window.adsbygoogle || []).push({});