好的代码

刚刚写代码的时候,对某个函数的调用进行了思考和修改,发现修改结果有很大的好处。把这个记录下来,努力让自己以后写代码都能这样思考。

原先的代码是这样的:

export default {
    getBoundingRect() {
                let el = this.getElement();
        let bounding = el.getBoundingClientRect();
        return {
            w: bounding.width,
            h: bounding.height,
            x: 0,
            y: 0
        }
    }
}

这段代码的作用是用户提供的重载方法,用来重载某个基础类的某个方法,这个基础类的代码基本如下:

class BaseClass {
    constructor(spec) {
         this.spec = spec;
    }

   getElement() {
        return document.body;
   }

   getBoundingRect() {  
       if (this.spec.getBoundingRect) {
            return this.spec.getBoundingRect.call(this);
       } else {
            return {};
       }
   }
}

所以当用户想要自定义getBoundingRect的行为时,可以提供一个重载的方法,即上面的代码。上面的代码是没有任何问题的,只是,考虑到代码的耦合度,还是需要修改的。

上面代码的方法中调用了基础类的一个getElement方法,也就是说这个方法依赖基础类的一个方法。那么问题来了,如果以后基础类要做一些调整,更改了getElement方法的名字,或者参数,那么所有用户的重载方法可能就都会报错了。这就是过多依赖的一个弊端。

好,既然有问题,那么就对我们的基础类做些修改,避免用户这样的使用。我们在基础类的getBoundingRect方法中,调用getElement方法,将返回值以参数的形式传给用户的重载方法。这样即使基础类的getElement方法改了,我们要做的修改仅仅限于这个类,减少了对用户自定义代码的影响。

修改后的代码:

export default {
    getBoundingRect(el) {
        let bounding = el.getBoundingClientRect();
        return {
            w: bounding.width,
            h: bounding.height,
            x: 0,
            y: 0
        }
    }
}
class BaseClass {
    constructor(spec) {
         this.spec = spec;
    }

   getElement() {
        return document.body;
   }

   getBoundingRect() {  
       let el = this.getElement();
       if (this.spec.getBoundingRect) {
            return this.spec.getBoundingRect(el);
       } else {
            return {};
       }
   }
}