构造函数不同但复用相同方法的类,如何避免代码重复?
代码去重方案:统一实例引用+基类继承
你遇到的核心问题是子类里的Shape实例变量名不统一(this.rec/this.hex),导致基类无法复用通用方法。解决思路很简单:统一子类中Shape实例的变量名,再通过基类封装通用逻辑。
具体重构步骤
- 创建通用基类:把
plotShape这类重复方法放到基类里,方法内统一用this.shape访问Shape实例的属性。 - 子类统一实例命名:Rectangle、Hexagon等子类继承基类,在构造函数中将Shape实例赋值给
this.shape(不再用this.rec/this.hex)。 - 删除子类重复代码:去掉子类里和基类重复的方法,直接继承使用。
重构后完整代码示例
1. 原Shape类保持不变
export class Shape { constructor (options) { this.size = options.size this.type = options.type switch (this.type) { // 其他case保留 case 4: this.gridsizex = options.gridsizex this.gridsizey = options.gridsizey break case 6: this.gridsize = options.gridsize break } this.xCoordinates = new Float64Array() this.yCoordinates = new Float64Array() } createShape() { this.xCoordinates = new Float64Array(this.size * this.size) this.yCoordinates = new Float64Array(this.size * this.size) switch (this.type) { // 其他case保留 case 4: for (let i = 0; i < this.size; i++) { for (let j = 0; j < this.size; j++) { let pos = i * this.size + j this.yCoordinates[pos] = i * this.gridsizey this.xCoordinates[pos] = j * this.gridsizex } } break case 6: let distXh = this.gridsize let distYh = distXh * Math.sqrt(3)/2 // 补全六边形Y轴间距计算 for (let i = 0; i < this.size; i++) { for (let j = 0; j < this.size; j++) { let pos = i*this.size+j this.yCoordinates[pos] = i * distYh this.xCoordinates[pos] = (j * distXh + i * (distXh / 2)) while ((this.xCoordinates[pos] - (this.size * distXh)) >= 0) { this.xCoordinates[pos] -= (this.size * distXh) } } } break } } }
2. 新增通用基类ShapeWrapper
class ShapeWrapper { // 通用方法:所有子类共享 plotShape(plot) { plot.data = { xAxis: this.shape.xCoordinates, yAxis: this.shape.yCoordinates, } } // 可在此添加更多通用方法,比如getCoordinates、updateSize等 }
3. 重构Rectangle和Hexagon子类
class Rectangle extends ShapeWrapper { constructor(options) { super() // 必须调用父类构造函数 this.size = options.size this.gridsizex = options.gridsizex this.gridsizey = options.gridsizey // 统一用this.shape存储Shape实例 this.shape = new Shape({ size: this.size, type: 4, gridsizex: this.gridsizex, gridsizey: this.gridsizey // 修正原代码拼写错误grdisizey }) this.shape.createShape() } // 去掉重复的plotShape方法,直接继承父类的 } class Hexagon extends ShapeWrapper { constructor(options) { super() this.size = options.size this.gridsize = options.gridsize this.shape = new Shape({ size: this.size, type: 6, gridsize: this.gridsize }) this.shape.createShape() } // 去掉重复的plotShape方法 }
4. 使用方式不变
// 修正原代码拼写错误Retangle -> Rectangle const recShape = new Rectangle({ size: 6, gridsizex: 3, gridsizey: 2, }) const hexShape = new Hexagon({ size: 6, gridsize: 1, }) function depiction(){ recShape.plotShape(shapePlot) hexShape.plotShape(shapePlot) }
额外优化建议
- 可以把Shape的
createShape调用放到基类构造函数里,进一步减少子类重复代码:class ShapeWrapper { constructor(shapeOptions) { this.shape = new Shape(shapeOptions) this.shape.createShape() } plotShape(plot) { ... } } // 子类构造函数简化为: class Rectangle extends ShapeWrapper { constructor(options) { super({ size: options.size, type: 4, gridsizex: options.gridsizex, gridsizey: options.gridsizey }) // 如需保留子类自身属性,再单独赋值 this.gridsizex = options.gridsizex this.gridsizey = options.gridsizey } } - 后续新增更多形状类(如Circle)时,只需继承ShapeWrapper并传入对应Shape配置,即可完全复用通用方法。
内容的提问来源于stack exchange,提问作者Tobias Dräger
相关产品推荐
相关产品推荐

