For*_*vin 5 javascript anti-patterns node.js eventemitter es6-class
如果您希望您的类支持事件,那么从 EventEmitter 继承似乎是常见的做法。例如,Google 为Puppeteer执行此操作,WebSocket 模块执行此操作,mongoose 执行此操作,...仅举几例。
但这真的是好的做法吗?我的意思是它看起来确实漂亮干净,但从 OOP 的角度来看,这似乎是错误的。例如:
const EventEmitter = require('events')
class Rectangle extends EventEmitter {
constructor(x,y,w,h) {
super()
this.position = {x:x, y:y}
this.dimensions = {w:w, h:h}
}
setDimensions(w,h) {
this.dimensions = {w:w, h:h}
this.emit('dimensionsChanged')
}
}
Run Code Online (Sandbox Code Playgroud)
看起来 Rectangle 的核心是一个 EventEmitter,尽管事件功能是次要的。
如果您决定Rectangle现在需要从一个名为 的新类继承怎么办Shape?
class Shape {
constructor(x,y) {
this.position = {x:x, y:y}
}
}
class Rectangle extends Shape {
constructor(x,y,w,h) {
super(x,y)
this.dimensions = {w:w, h:h}
}
}
Run Code Online (Sandbox Code Playgroud)
现在您必须Shape从 EventEmitter 继承。即使只有一个继承自的类Shape实际上需要事件处理。
这样的事情不是更有意义吗?
class Shape {
constructor(x,y) {
this.position = {x, y}
}
}
const EventEmitter = require('events')
class Rectangle extends Shape {
constructor(x,y,w,h) {
super(x,y)
this.dimensions = {w, h}
this.em = new EventEmitter()
}
setDimensions(w,h) {
this.dimensions = {w:w, h:h}
this.em.emit('dimensionsChanged')
}
}
const rectangle = new Rectangle(1,2,3,4)
rectangle.em.on('dimensionsChanged', ()=>{console.log('dimensions changed')})
rectangle.setDimensions(10,20)
Run Code Online (Sandbox Code Playgroud)