代码规范

159 阅读3分钟

1. 单一职责原则

这是经常被违背的原则, 也是最难运用好的原则.

  • 一个类只做一类相关的事情
  • 一个函数/方法, 最好只做一件事情

2. 行为是否统一

1) 什么是行为统一? 例如:

  • 错误处理是否统一
  • 错误提示是否统一
  • 弹出框是否统一
  • ...

2) 同一逻辑/行为, 有没有执行同样的代码路径

低质量的代码一个特征是, 同一逻辑/行为, 在不同的地方或不同的方式触发时, 没有执行同样的代码路径(产生出不同的结果), 或者是各处copy一份实现, 导致非常难以维护.

3. 代码污染

代码有没有对其他模块强耦合

4. 重复代码

主要看有没有把公用组件, 可复用的代码、函数抽取出来

5. 开放-封闭原则

简单理解是, 看代码好不好扩展

6. 健壮性

  • 核心数据有没有强制校验?
  • 对业务有没有考虑完整, 逻辑是否健壮
  • 有没有潜在的bug?
  • 有没有内存泄露?有没有循环依赖?

7. 错误处理

有没有很好的Error Handling? 如网络出错, IO出错等.

8. 面向接口编程/面向对象接口编程

主要看有没有进行合适的抽象, 把一些行为抽象为接口

9. 效率/性能

  • 客户端程序对频繁的消息和较大数据等耗时操作是否处理得当
  • 关键算法的时间复杂度是多少? 有没有潜在的性能瓶颈?

10. 代码重构

  • 新的改动是打补丁, 让代码质量继续恶化, 还是对代码质量提升有帮助?

低质量代码的常见特征

  • 违反"单一职责"原则
  • 同一逻辑/行为, 通过不同的方式触发时, 不会执行同样的代码路径
  • 缺少注释
  • 函数/类命名乱, 词不达意, 或"挂羊头卖狗肉", 例如
export function setDefaultImg(res) {
    let imgUrl = getImagePrefixUrl()
    let previewImgSrc = require('@/asserts/images/icon.png')
    if(res.imgId) {
        previewImgSrc = `${imgUrl}${res.imgId}.${res.type}?t=${+new Date()}`
    }
    return previewImgSrc
}

上例函数, 其实是想对传入的参数进行判断, 如果值无效, 取默认图片, 否则返回拼接地址好的img src相对地址. 从函数的实现来看, 有如下几个问题:

  • 函数名setDefaultImg并不合适, 无任何对数据的更新/修改, 最终目的是想拿到img的拼接地址(或者默认图片)
  • 形参res是一个对象, 实际使用到的属性只有两个基本类型, 遵循最少知识原则, 应修改形参.
  • let imgUrl, 其实是拼接url的前缀, 取名如 imgPrefixUrl会比较合适.
  • let 使用不当, 如 let imgUrl, 因涉及不到变量再赋值, 使用const是比较合适的
  • res.imgId, 即异常情况的处理, 少了对res.type的处理
  • 变量命名, 如previewImgSrc, 取此名也不太合适, 该src使用的目的并不确定, 建议使用有比较通用涵义的名字.

可考虑重构为:

export function getImgSrc(imgId, imgType) {
    if(typeof imgId !== 'string' || typeof imgType !== 'string') {
        return require('@/asserts/images/icon.png')
    }
    return `${getImagePrefixUrl()}${imgId}.${imgType}?t=${+new Date()}`
}

参考资料:

juejin.cn/post/684490…

juejin.cn/post/684490…