介绍
- 发布订阅
- 一对多(1对n)
示例
- 订报纸
- 订牛奶
UML类图
代码
// 保存所有状态,状态变化后触发所有观察者对象class Subject {constructor() {this.state = 0this.observers = []}getState() {return this.state}setState(state) {this.state = statethis.notifyAllObservers()}attach(observer) {this.observers.push(observer)}notifyAllObservers() {this.observers.forEach(observer => {observer.update()})}}// 观察者class Observer {constructor(name, subject) {this.name = namethis.subject = subjectthis.subject.attach(this)}update() {console.log(`name:${this.name} update, state: ${this.subject.getState()}`);}}// testconst s = new Subject()const o1 = new Observer('o1', s)const o2 = new Observer('o2', s)const o3 = new Observer('o3', s)s.setState(1)
场景
- 网页事件绑定 ```html
- Promise- jquery callbacks- nodejs 自定义事件- EventEmitter```javascriptconst EventEmitter = require('events').EventEmitterconst events = new EventEmitter()// 监听 some 事件events.on('some', info => {console.log('fn1', info)})// 监听 some 事件events.on('some', info => {console.log('fn2', info)})// 触发 some 事件events.emit('some', 'xxxxxx')
const EventEmitter = require('events').EventEmitterclass Dog extends EventEmitter {constructor(name) {super()this.name = name}}let dog = new Dog('dog1')dog.on('bark', (name) => {console.log(name, 'bark-1')})dog.on('bark', (name) => {console.log(name, 'bark-2')})setInterval(() => {dog.emit('bark', 'ss')}, 1000)
- Stream ```javascript const fs = require(‘fs’) const path = require(‘path’)
const stream = fs.createReadStream(path.resolve(__dirname, ‘../release/bundle.js’))
let length = 0 stream.on(‘data’, (chunk) => { let len = chunk.toString().length console.log(‘len’, len); length += len }) stream.on(‘end’, () => { console.log(‘length’, length); })
- readline```javascriptconst readline = require('readline')const fs = require('fs')const path = require('path')const rl = readline.createInterface({input: fs.createReadStream(path.resolve(__dirname, '../package-lock.json'))})let lineNum = 0rl.on('line', (line) => {lineNum++})rl.on('close', () => {console.log('lineNum', lineNum)})
- nodejs中处理http请求(post),多进程通信(child_process)
- vue,react组件生命触发
- vue的watch
设计原则验证
- 主题和观察者分离,不是主动触发,而是被动监听,两者解耦
- 符合OCP
