“可读性 + 可维护性 是再怎么强调都不为过的代码质量标准 —— 不要刻意为了重用代码而抽象,更不要为了抽象而抽象 ,多思考代码的语义、概念”
比如工作的项目上遇到了一些代码复用
有几个地方为了复用一些 看起来 重复的代码,但实际上它们有不同的业务概念,在不同的业务逻辑和不同的业务场景里,也强行抽出一个公用的组件,“封装”了所谓的重复代码。
同时,因为使用场景非常不同,这个组件不得不在内部写下了大量的 if else 判断条件 以表达“如果是场景X就走这条路;如果是场景Y就走那条路...”
更可怕的是,核心逻辑被一而再再而三地往深处抽象,导致我一开始打算了解这个组件时,不得不一层层得往下阅读代码(当然也包括走向不同的 if else 的情况)
最后的结果是,这个组件对于后来的维护者仿佛是一个噩梦,既难以阅读更难以使用。
封装的根本目的是 代码复用 吗? 不,我认为不是。
我认为 封装的根本目的 是 让代码更容易维护,而代码复用通常是封装带来的一个副作用。
我们经常听到的 同时推崇 封装 + 代码复用 的说法:
这样可以避免重复的代码,让代码更简洁;
当被封装的代码实现需要改变时就不需要去更改调用的地方(只改一处而不是改多处)
让代码更简洁也好,不需要多处改代码也好 —— 都是表象,而不是根本。根本是提高代码的可维护性。
正是希望代码更容易维护,我们才尽量让代码简洁一点;正是希望代码更容易维护,我们才希望更改实现时,不需要动太多处代码。原谅我这边略显啰嗦,我只是希望大家能看清我们做封装的初衷,而不是僵硬地盲目地遵循一些所谓的原则。
换句话说,假如 封装 使代码更难维护了,那就算它复用了再多的代码也是一个错误的做法!
以我上面举的例子,有个需求是让我改变这个组件在 X场景下的某个行为,我发现我无法轻松地做到,我得查到组件里那些复杂的 if else 的那条”正确“的路径 ,小心翼翼地更改,生怕影响到其他地方 —— 如此憋屈的体验让我愤然在这个组件头写下一条注释 :”重构这个组件,让它对开发者更友好,否则就废弃掉它! “(现在我是这个项目负责人,所以这个事大概率后面也是我去做)
简单总结一下:
- 封装的初衷是让代码更容易维护,而不是纯粹是为了复用代码
- 假如封装后让代码更加僵硬,更难以维护,那么宁愿放弃这个封装,忍受一部分的代码重复 或者 重新考虑封装的思路
- 软件开发没有亘古不变的金科玉律,结合实际业务场景,谨慎设计代码,不要为了封装而封装。
——海云前端,提供1对1前端简历面试辅导、前端私教课、前端项目难点笔记、语音咨询、模拟面试