美文网首页scala工具集
抛弃代码的坏味道 - 提升代码质量之可读性

抛弃代码的坏味道 - 提升代码质量之可读性

作者: 小赵营 | 来源:发表于2019-09-17 18:58 被阅读0次

    [写在开始]代码质量是每个项目都在呼吁的。却是大家都不愿实施的。长期效益诱惑抵抗不了短期收益的现实。目前,它给予的程序猿只有自我满足和成就感。一个深陷老旧系统无法脱身程序员面对代码无奈大家都有耳闻。在追求交付至上的项目,代码质量问题不是团队、项目、公司面临的问题,只属于程序猿。

    代码质量

    最近花时间整理:我对代码的可读性和可测试性理解。代码质量提升又没有统一标准,如果寻找不可能完成的任务:说服程序猿修改自己的代码,一定包含其中。所以,本文纯属个人理解。

    这篇文章分为2部分:代码可读性和代码可测试性。

    可读性和可测试是没有统一的量化标准,尤其是新语言不断涌现的。

    一切量化指标都有纲领性文件。本文指导性纲领:最为我们熟知的是SOLID, KISS, DRY ...。内容是他们的具体化。

    1、注释可读性原则

    代码用来维护和阅读的"文档",代码是功能最直接的传达者。而注释是为什么要如此传达的解释。开发模式摒弃注释本身就不利于代码可读性和可维护性。注释编写包括如下几个方面。

    • 注释内容
      注释描述为什么code,而不是code是什么。最好描述code是什么的是:代码实现,而不是字面的描述。而为什么这么做,是代码无法描述的。
    • 注释变化
      保持注释持续更新,使之与当前实现匹配。不匹配的注释非但不是理解code的助推器,反而是阻燃剂。
    • 不要添加无意义的注释
    • 不增加的关于调试信息描述
    getUTCTime()// debug:获取UTC 用于记录耗时
    
    • 不要无意义的注释
    new Date() // 生成Date 信息
    

    以上反例表明:能用代码解决的就不要加注释。

    • 注释跟踪
      注释跟踪:记录代码注释历史。既为了追溯,也便于阅读者和修改方进行信息传递。

    2、通用可读性原则

    通用原则指对变量、方法、以及类都适用的原则。

    • 格式规范化
      项目规范代码格式化内容。诸如 空格缩进、方式修饰符使用、{}、if ...else.. 等控制关键字使用、驼峰式命名或者匈牙利命名等。规划化的格式才是代码可读性的基础。
    • 命名规范化
      • 英文使用规划化
        比如:修复对应的英文, 包括repair fix ...。如何选择合适的词汇来描述。尽量使用软件行业专用词汇,对老旧系统即使无法统一,也不要出现相同术语而使用不同的词汇。
      • 不要在命名中嵌入数据类型尤其是函数中
    //功能是把日期转换成Int,这是不建议的方式,*函数的返回类型*标识的Int
    //函数中加入类型是画蛇添足
    .... //伪代码
      getDate2Int() 
    
    • 使用好的框架
      避免重复造轮子,使用好的框架。在每个领域都有优秀的开源框架。如数据库连接池管理库Druid HikariCP DBCP...,线程池管理框架、支持缓存的Redis,CacheMem。优秀的框架即战力很强大,我们都值得拥有。

    • 避免重复的代码
      坚持DRY(don't repeat yourself.)原则一百年不动摇。

    • 代码模块化
      模块化没有直接受益,我只能说对可读性而言太重要
      模块化和组件化设计意味着最小知识、技能和依赖在系统中,防止教条出现、构建抽象层、避免设计复杂的相互依赖、功能独立性等....

    • 代码review原则

    让review真正运作起来。review代码是检验可读性最佳标准。review过程中的,信息沟通和经验传递是提升编码水平和形成习惯的最佳途径。

    • 给代码以时间

    套用大刘的这句话。试想几个月后甚至更久后,我们回看代码,若逻辑不清晰、结构待调整,说明代码可读性有提升空间。如果你意识到代码可读性差,也表明个人能力提升。所以一切交给时间吧。

    3、函数可读性原则

    • 函数简短化
      受过长函数苦的,就不要让其它人继续受累。我们不武断提倡每个函数少于5行,但绝不让它们超过 50行。
    • 参数列表简短化
      限制参数的长度, 3~5个为宜。过长的参数列表,往往意味这超长的函数和复杂代码逻辑。
    • 参数最小化原则
      遵守参数最小化原则,即不需要的参数不用传入。参数没有最小化,是代码腐化的主要原因。
    calss Person(name: String, addr: String, age: Int, sex: String)
    def isFemale(person: Person): Boolean = {
        ....
    }
    

    上例中判断是否是性别,只用传入sex就满足功能要求,传入的参数是Person 违背参数最小化原则。

    • 代码执行逻辑统一
      我们功能实现时,过程控制条件太多,且没有统一逻辑。代码经常看到if ...else...满天飞,但细读下来各个分支逻辑并不同。如下正例:都是根据小时条件生成结果。反例则可读性不高。
    {
       DateTime time = DateTime.Now;
       if (time.Hour >= 0 && time.Hour < 6)
       {
           return "Night";
       }
       if (time.Hour >= 6 && time.Hour < 12)
       {
           return "Morning";
       }
      ....
       return "Evening";
    }
    //反例,lineitem card并不是一个维度内容
    if (lineItem != null && (lineItem.quantity > 0 && customer.isActive() && (card.expirityYear > 2010 || card.type == AMX)) || couponCode.isValid()) {
    // details..
    }
    //封面图是又一可读性反证
    
    • 代码有效性
      义无反顾的删除过期代码和调试代码。减少无用日志输出。让代码有意义

    • 单一职责
      就是我们常说的SRP。就函数而言,保证以上原则SRP就满足了。

    3、类可读性原则

    • 数据类和实现类分离
      数据的提供者和使用者分离。避免类中存储数据,外部数据在类生成时传入,类只负责对数据的操作。

    • 不同类提供不同接口
      如果内部相似的类,对外却提供不同的接口,让其接口统一:创建接口层,etc.保持内外提供相同接口。

    • 简化初始化逻辑
      面向对象编程,多重继承让类初始化逻辑异常复杂。为了简化逻辑,类初始化逻辑耦合尽量小。

    • 减少类接口暴露数量
      是时候使用访问级别修饰符限定访问权限,和简化对外接口。

    • 明确函数归属原则
      若函数实现依赖其它类,那么它属于依赖函数,而不是当前类。

    • 隔离依赖
      常见场景:依赖库如无法进行修改,为了将来便于使用新依赖库,构造接口类进行隔离。防止对旧有库的行为使用。

    • 废弃任何不必须类
      任何类都会增加项目的复杂度,多余功能类进行废弃和合并

    • 重构类
      如果一个类修改,同时要修改若干其它类,对该类进行进行重构。保证修改仅限在一个类中。新需求引入稳定系统,可行性方案越少,越利于维护。系统腐化的风险越小。

    后续

    代码可读性个人性很强。不同的阶段,对美的理解不同。就如同欣赏NBA比赛,时间久了,马刺黑,也会成为刺蜜。品味是个很玄幻的东西,要个人努力和时间积累。

    一切的提升源于认识深入。

    喜欢就冒个泡或赏个赞哈

    相关文章

      网友评论

        本文标题:抛弃代码的坏味道 - 提升代码质量之可读性

        本文链接:https://www.haomeiwen.com/subject/blmbyctx.html