观察者模式
// 首先明白定义 观察则模式定义了一种 一对多的关系 多个观察者监听同一个目标对象,当这个目标对象发生变化时会通知所有的 观察者,观察则自动更新
// 所以在这里认为 这是两方的事情 是被观察者 和观察者 之间直接联系无中间者参与,还有就是 被观察者通知观察者的变化
abstract class Student {
constructor(public teacher: Teacher) {
}
// 每个观察者都有一个update方法 用来在被观察对象更新的时候 执行更新或触发方法
public abstract update(): void
}
class Xueba extends Student {
public update(): void {
if (this.teacher.getState() === 'tiwen') {
console.log(this.teacher.getState(), 'huidatiwen')
}
}
}
class Xuezha extends Student {
public update (): void {
if (this.teacher.getState() === 'tiwen') {
console.log(this.teacher.getState(), 'ditibibi')
}
}
}
class Teacher {
private state: string = 'jiangke'
private students: Student[] = []
public askQuestion () {
this.state = 'laoshitiwen'
this.notifyAllStudents()
}
getState() {
return this.state
}
setState () {
}
attach (student: Student) {
this.student.push(student)
}
notifyAllStudents () {
this.students.forEach(student => student.update())
}
}
let teacher = new Teacher ()
teacher.attach(new Xueba(teacher))
teacher.attach(new Xuezha(teacher))
teacher.askQuestion() // 老师发生事件 状态变化 通知学生 (观察者)
// 在上边的例子中 老师中有 学生的数组, 学生中也有老师的实例 所以这里是关键
// 观察者常用的应用场景
- // DOM事件绑定
- // Promise
- // callback
- // 生命周期函数
- // EvetBus
- // Vue2响应式原理
- // redux
发布订阅者模式
- // 订阅者 把自己想 订阅的事情注册到 调度中心
- // 发布者 把要发布的事件 发布到 调度中心
- // 然后, 调度中心统一调度 订阅者注册到调度中心的代码
// 虽然 以上两种模式都有发布者和订阅者 ,但是观察者模式中调用是被观察者发布 而发布订阅者是有调度中心的 , 所以观察者模式 是发布和订阅者之间是相互知道的 但是发布订阅模式中是不知道的
// 下面的例子以 租房者 中介和 房东为例子
// 中介
class Agency {
_topic = {} // envents
subscirbe(type, listener) {
let listeners = this._topic[type]
if (listener) {
listeners.push(listener)
} else {
this._topic[type] = [listener]
}
}
publish (type, ...args) {
let listeners = this._topic[type] || []
listeners.forEach(listener => listener(...args))
}
}
// 房东
class LandLord {
constructor (public agency: Agency) {
}
// type 房子类型 area面积 money 房租价格
lend(type, area, money) {
this.agency.publish(type, area, money)
}
}
// 房客
class Tenant {
constructor (public angency: Angency, public name: string) {
}
order (type) {
this.angency.subscirbe(type, (area, money) => {
console.log(this.name, area + money)
})
}
}
// 搞一个中介
let angency = new Angency()
// 搞两个租客
let rich = new Tenant(angency, 'rich')
let beipiao = new Tenant(angency, 'beipiao')
rich.order('haozhai')
beipiao.order('danjian')
// 搞一个房东
let landLord = new LandLord()
landLord.lend('haozhai', 1000, 100000)
landLord.lend('danjian', 10 ,2000)