学起来,你的项目也应该有一个方法库

135 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

变量提炼

程序之中,复杂的条件逻辑往往是导致复杂度上升的原因之一,在《重构》一书中,有这样一种重构手法,叫做分解条件表达式,就是为了直观的察觉代码运行顺序,通过提炼判断语句里的条件,用更为语义话的手法去封装判断条件,具体实例如下:

if(data.isComputed === true && data.number === 100){
    result = '满分'
}else{
    result = '未满分'
}

// 上面的条件语句可以替换成下面的条件语句
const isFull = data.isComputed === true && data.number === 100
if(isFull){
    result = '满分'
}else{
    result = '未满分'
}

上面的操作在《重构》一书中称为提炼变量,而我们可以通过变量的语义化更直观看到代码执行。

而实际上个人建议在判断语句较长的情况下可以使用提炼的手法用变量去代替判断条件。

方法封装

当一个判断条件较长且经常出现,在《重构》一书中也推荐我们另外一个手法,叫做封装,即在运用分解条件表达式的手法时,把判断条件封装起来,或者通过传参的形式计算出结果,示例如下:

if (Array.isArray(data) && data.length) {
    data.forEach(item => console.log(item))
}

// 封装的方法库
const isNotEmptyArray = data => Array.isArray(data) && data.length

if (isNotEmptyArray(data)) {
    data.forEach(item => console.log(item))
}

方法抽离

在你的工程里建议有一个shared文件,专门存储你封装的方法,又或者可以写入你的utils目录下。当你需要使用诸如判断方法时,可以通过调用的方式直接引入。

或许你会认为这不是多此一举吗?实际上,方法调用在代码维护上起码能够让人直观看出代码的作用,而不必关心起内部实现,当然其重点还是要依托于方法名的规范命名。

而且对于多次调用的方法,在打包优化过程中,也可以对其进行公共抽离,降低一丢丢的代码体积。

对于冗长的、重复的条件语句,我认为这种方法是十分有用的。

实际上,我们经常重复调使用一些冗长的条件判断,譬如判断非空数组,判断promise、判断平面对象、克隆处理等。

当然,对于简短而少见的判断,我们就没必要为其抽离啦。

抽离的依据

我们可以学习主流源码库的工程项目结构,学习其分层与架构设计。 下面我们看看几个流行库里对于方法抽离的设计。

lodash的通用方法抽离

lodash里通用方法封装在/.internal目录下,并且是以一个文件一个通用方法的形式。

image.png

示例代码如下:

// copyArray.js文件
function copyArray(source, array) {
    let index = -1
    const length = source.length

    array || (array = new Array(length))
    while (++index < length) {
        array[index] = source[index]
    }
    return array
}

export default copyArray

vue中的公用方法抽离

在vue源码里的shared目录下存在如下文件,主要是对常用的方法进行封装:

image.png

查看utils下的内容,我们可以发现是对常用方法的封装,诸如判断数组,判断数据类型等。

image.png

示例代码如下:

export function isTrue(v: any): boolean {
    return v === true
}

export function isFalse(v: any): boolean {
    return v === false
}

可能有人认为上面的这种封装似乎没什么意思,但是当一个项目使用次数多了,代码长度会显得更长,同时封装好的命名能够更加语意化。

react中的公用方法抽离

相比vue,react中的公用方法则和lodash类似,也是以平面铺开的形式,一个方法一个文件。

image.png 示例代码如下:

// isArray.js文件
declare function isArray(a: mixed): boolean % checks(Array.isArray(a));

const isArrayImpl = Array.isArray;

function isArray(a: mixed): boolean {
    return isArrayImpl(a);
}

export default isArray;

// hasOwnProperty.js文件
const hasOwnProperty = Object.prototype.hasOwnProperty;

export default hasOwnProperty;

小结

本篇章我们主要是通过查看主流开源库的工程结构设计,提出了在实际项目中应当建立通用方法库。

并且我们也学习了相应的重构手法,在判断语句里应该应用提炼和封装等手法让代码更加直观。