如何解决从 EventEmitter 继承是一种反模式吗?
如果您希望您的类支持事件,那么从 EventEmitter 继承似乎是一种常见的做法。 例如,Google 为 Puppeteer 执行此操作,WebSocket module 执行此操作,mongoose does it,...仅举几例。
但这真的是好习惯吗?我的意思是肯定它看起来漂亮干净,但从 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')
}
}
即使事件功能是次要的,也会使 Rectangle 看起来像是一个 EventEmitter 的核心。
如果您决定 Rectangle
现在需要从名为 Shape
的新类继承怎么办?
class Shape {
constructor(x,y) {
this.position = {x:x,y:y}
}
}
class Rectangle extends Shape {
constructor(x,h) {
super(x,y)
this.dimensions = {w:w,h:h}
}
}
现在您必须使 Shape
从 EventEmitter 继承。即使只有一个继承自 Shape
的类实际上需要事件处理。
这样的事情不会更有意义吗?
class Shape {
constructor(x,y) {
this.position = {x,y}
}
}
const EventEmitter = require('events')
class Rectangle extends Shape {
constructor(x,y)
this.dimensions = {w,h}
this.em = new EventEmitter()
}
setDimensions(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)
解决方法
是的,这绝对更有意义。
应该使用继承来表示 is a 关系:class Rectangle extends Shape
是可以的,因为 Rectangle
是一个形状,但这里的矩形本身不是一个 em> EventEmitter
。
相反,我们有一个 can 关系:Rectangle
可以发出一个事件,这正是您应该支持 composition over inheritance 的地方,它是在您的最后一个代码片段中发生的事情。
我们只能推测为什么一些著名的库不这样做 - 复古兼容性、API 的简单性,或者只是糟糕的设计。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。