You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构造函数不同但复用相同方法的类,如何避免代码重复?

代码去重方案:统一实例引用+基类继承

你遇到的核心问题是子类里的Shape实例变量名不统一(this.rec/this.hex),导致基类无法复用通用方法。解决思路很简单:统一子类中Shape实例的变量名,再通过基类封装通用逻辑。

具体重构步骤

  1. 创建通用基类:把plotShape这类重复方法放到基类里,方法内统一用this.shape访问Shape实例的属性。
  2. 子类统一实例命名:Rectangle、Hexagon等子类继承基类,在构造函数中将Shape实例赋值给this.shape(不再用this.rec/this.hex)。
  3. 删除子类重复代码:去掉子类里和基类重复的方法,直接继承使用。

重构后完整代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:34:58