如何评价代码质量

设计模式专栏: http://t.csdnimg.cn/4Mt4u

目录

1.引言       

2.可维护性(maintainability)

3.可读性(readability)

4.可扩展性(extensibility)

5.灵活性(flexibility)

6.简洁性(simplicity)

7.可复用性(reusability)

8.可测试性(testability)

9.总结


1.引言       

        在作者的工作经历中,每当同事评论项目代码质量的时候,作者听到最多的评论是“代码写得很烂”或“代码写得很好”。作者认为,用“好”“烂”这样的字眼来描述代码质量是笼统的。当作者询问代码到底“烂”在何处或“好”在哪里时,尽管大部分同事都能简单列几个“烂”的方面或好的方面,但他们的回答往往都不够全面,知识点零碎,也无法切中要害。

        当然,也有一些软件工程师对如何评价代码质量有所认识,如认为好代码是易扩展、易读简单、易维护的,等等,但他们对于这些评价的理解往往只停留在表面上,对于诸多更加深入的问题,如“怎么才算可读性好?什么样的代码才算易扩展、易维护?可读、可扩展与可维之间有什么关系?可维护中的'维护’两字该如何理解?”,等等,他们并没有太清晰的认识。

        实际上,对于代码质量的描述,除“好”“烂”这样比较简单、笼统的描述方式以外,有很多语义丰富、专业和细化的描述方式,如下所示:

        灵活性(fexibility)、可扩展性(extensibility)、可维护性(maintainability)、可读性(readability)可理解性(understandability)、易修改性(changeability)、可复用性(reusability)、可测试(testability)、模块化(modularity)、高内聚低耦合(highcohesion loosecoupling)、高效(higheffciency)、高性能(high performance)、安全性(security)、兼容性(compatibility)、易用性(usability)、简洁(clean)、清晰(clarity)、简单(simple)、直接(straightforward)、少即是多(less code is more)、文档详尽(well-documented)、分层清晰(well-layered)、正确性(correctness、bug free)、健壮性(robustess)、鲁棒性(robustess)、可用性(reliability)、可伸缩性(scalability)、稳定性(stability)和优雅(elegant)等。        

        面到如此多的词汇,我们到底应该使用哪些词汇来描述一段代码的质量呢?

        实际上,我们很难通过其中的某个或某几个词汇来全面地评价代码质量,因为这些词汇是从不同角度描述代码质量的。例如,在评价一个人的时候,我们往往通过多个方面进行综合评价,如性格、能力等,否则,对一个人的评价可能是片面的。同样,对于代码质量,我们也需要综合多种因素进行评价,不应该从单一的角度去评价。例如,一段代码的可扩展性很好,但可读性很差,那么,我们不能片面地认为这段代码的质量高。

        注意,不同的评价角度并不是完全独立的,有些之间存在包含关系、重叠关系等,或者可以互相影响。例如,代码的可读性和可扩展性好,可能意味着代码的可维护性好。而且,各种评价角度不是“非黑即白”。例如,我们不能简单地将代码评价为可读或不可读。如果用数字来量化代码的可读性,那么应该是一个连续的区间值,而非0、1这样的离散值。

        不过,我们真的可以客观地量化一段代码的质量吗?答案是否定的。对一段代码质量的评价,常常带有很强的主观性。例如,对于什么样的代码才算是可读性好,每个人的评判标准都不一样。

正是因为代码质量评价的主观性,使得这种主观评价的准确度与软件工程师自身的经验有极大的关系。软件工程师的经验越丰富,给出的评价往往越准确。形成对比的是,资历较浅的软件工程师常常觉得没有一个可量化的评价标准作为参考,很难准确判断一段代码的质量。如果无法辨别代码写得好或坏,那么,即使写再多的代码,编码能力也可能没有太大提高。

        在仔细阅读前面罗列的代码质量评价标准之后,读者会发现,有些词汇过于笼统、抽象而且偏向于对整体的描述,如优雅、好、坏、整洁和清晰等;有些过于注重细节、偏重方法论,如模块化、高内聚低耦合、文档详尽和分层清晰等;有些可能并不仅仅局限于编码,与架构设计等也有关系,如可伸缩性、可复用性和稳定性等。

        为了读者有重点地进行学习,作者挑选了7个常用且重要的评价标准来详细讲解,包括可维护性、可读性、可扩展性、灵活性、简洁性、可复用性和可测试性。

2.可维护性(maintainability)

        对于代码开发,“维护”无外乎修改 bug、修改旧的代码和添加新的代码等。“代码易维护”是指,在不破坏原有代码设计、不引入新的bug的情况下,能够快速修改或添加代码。“代码不易维护”是指,修改或添加代码需要冒极大的引入新 bug 的风险,并且需要很长的时间才能完成。

        对于一个项目,维护代码的时间可能远远大于编写代码的时间。软件工程师可能将大部分时间花在修复 bug、修改旧的功能逻辑和添加新的功能逻辑之类的工作上。因此,代码的可维护性就显得格外重要。

         对于维护、易维护和不易维护这3个概念,我们不难理解。不过,对于实际的软件开发更重要的是需要清楚如何判断代码可维护性的高低。实际上,可维护性是一个难以量化、偏向对代码整体进行评价的标准,它类似之前提到的“好”“坏”“优雅”之类的笼统评价。代码的可维护性高低是由很多因素共同作用的结果。代码简洁、可读性好、可扩展性好,往往就会使得代码易维护。更深入地讲,如果代码分层晰、模块化程度高、高内聚低耦合、遵守基于接口而非实现编程的设计原则等,就可能意味料代码易维护。除此之外,代码的易维护性还与项目的代码量、业务的复杂程度、技术的复杂程度、文档的全面性和团队成员的开发水平等诸多因素有关。具体的指标有:

  • 代码是否模块化良好,各模块职责明确?
  • 是否遵循了单一职责原则和开放封闭原则?
  • 代码的扩展性和修改是否容易?
  • 是否有合理的错误处理和异常管理机制?

3.可读性(readability)

        软件设计专家 Martin Fowler 曾经说过:“ Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”(任何人都可以编写计算机能理解的代码,而好的程序员能够编写人能理解的代码。)在Google内部,有一个称为“Readability的认证。只有拿到这个认证的软件工程师,才有资格在Code Review的时候批准别人提交的代码。可见,代码的可读性有多么重要,毕竟,代码被阅读的次数有时候远远超过被编写和执行的次数。

        代码的可读性如此重要,在编写代码的时候,我们要时刻考虑代码是否易读、易理解。代码的可读性在很大程度上会影响代码的可维护性,因为无论是修复bug还是添加/修改功能代码,我们首先要读懂代码。如果我们对代码一知半解,就有可能因为考虑不周而引入新bug。既然代码的可读性如此重要,那么我们如何评判一段代码的可读性呢?我们需要查看代码是否符合代码规范,如命名是否达意、注释是否详尽、函数长度是否合适、模块划分是否清晰,以及代码是否“高内聚、低耦合”等。除此之外,Code Review也是一个很好的测试代码可读性的手段。如果我们的同事可以轻松地读懂我们写的代码,往往能够说明我们的代码的可读性不差;如果同事在读我们写的代码时,有很多疑问,那么可能在提示我们,代码的可读性存在问题,需要重点关注。具体的指标有:

  • 代码是否简洁明了,易于理解?
  • 变量和函数命名是否清晰、具有描述性?
  • 代码结构是否逻辑清晰,避免了复杂的嵌套和冗长的代码块?
  • 是否使用了适当的注释来解释关键部分和逻辑?
  • 是否有适当的文档说明代码的功能、接口和使用方法?
  • 注释是否准确、简洁,有助于理解代码?

4.可扩展性(extensibility)

        代码的可扩展性是指在不修改或少量修改原有代码的情况下,能够通过扩展方式添加新功能代码。换句话说,代码的可扩展性是指在编写代码时预留了一些功能扩展点,我们可以把新助能代码直接插入扩展点,而不会因为添加新的功能代码而改动大量的原始代码。可扩展性构提评价代码质量的重要标准。代码的可扩展性表示代码应对未来需求变化的能力。与代码的可读性一样,代码是否易扩展也在很大程度上决定了代码是否易维护。

5.灵活性(flexibility)

        灵活性也可以用来描述代码质量。例如,我们经常会听到这样的描述:“代码写得很灵活”。那么,我们如何理解这里提到的“灵活”呢?

        尽管很多人用"灵活"描述代码质量,但实际上,"灵活"是一个抽象的评价标准,给"灵活"下定义是很难的。不过,我能可以想一下,我们在什么情况下才会说代码写的很灵活呢?作者罗列了3种场景,帮助读者理解什么是代码的灵活性

        1)当我们添加新功能代码时,由于原有代码中已经预留了扩展点,因此,我们不需要修改原有代码,只需要在扩展点上添加新代码。这个时候,我们除可以说代码易扩展以外,还可以说代码写得很灵活。

        2)当我们要实现一个功能时,如果原有代码中已经抽象出了很多位于底层且可复用的模块、类等,那么我们可以直接使用。这个时候,我们除可以说代码易复用以外,还可以说代码写得很灵活。

        3)当我们使用某个类时,如果这个类可以应对多种使用场景,满足多种不同需求,那么,我们除可以说这个类易用以外,还可以说这个类设计得很灵活或代码写得很灵活。

        从上述场景来看,如果一段代码易扩展、易复用,或者易用,我们一般可以认为这段代码写得很灵活。因此,“灵活”的含义宽泛,很多场景都可以使用。

6.简洁性(simplicity)

        有一条非常著名的设计原则,大部分读者应该都听过,那就是KISS原则:“Keep It Simple,Stupid”。该原则的意思是“尽量保持代码简单”。代码简单、逻辑清晰往往意味着代码易读、易维护。在编写代码的时候,我们往往会把“简单清晰”原则放到首位。

        不过,很多编程经验不足的程序员会觉得,简单的代码没有技术含量,喜欢在项目中引入一些复杂的设计模式,觉得这样才能体现自己的技术水平。实际上,思从深而行从简,真正的编程高手往往能用简单的方法解决复杂的问题。

        除此之外,虽然我们都能认识到,代码要尽量写得简洁,要符合KISS原则,但怎样的代码才算足够简洁?怎样的代码才算符合KISS原则呢?实际上,不是每个人都能准确地做出判断,因此,在后面介绍KISS 原则的时候,我们会通过具体的代码示例详细说明。

7.可复用性(reusability)

        我们可以将代码的可复用性简单地理解为“尽量减少重复代码的编写,复用已有代码”在后续章节中,我们会经常提到“可复用性”这一代码评价标准。例如,当介绍面向对象特性的时候,我们会提到继承、多态存在的目的之一就是提高代码的可复用性;当介绍设计原则的时候,我们会提到单一职责原则与代码的可复用性相关;当介绍重构技巧的时候,我们会提到解耦、高内聚和模块化等能够提高代码的可复用性。可见,可复用性是一个重要的代码评价标准,也是很多设计原则、设计思想和设计模式等所要实现的最终效果。

        实际上,代码的可复用性与 DRY(Don't  Repeat Yourself)原则的关系紧密,因此,在后面介绍DRY原则的时候,我们还会介绍代码复用相关的更多知识,如提高代码的可复用性的编程方法等。

8.可测试性(testability)

        相比上述6个代码质量评价标准,代码的可测试性较少被提及,但它同样重要。代码的可测试性的高低可以从侧面准确地反映代码质量的高低。代码的可测试性低,难以编写单元测试,那么,基本能够说明代码的设计有问题。关于代码的可测试性,我们会在后面继续讲解。

       具体的指标有:

  • 代码是否易于编写单元测试、集成测试和端到端测试?
  • 是否提供了必要的接口和钩子以便于测试?
  • 测试覆盖率是否足够高,能够覆盖关键功能和边界情况?

9.总结

        在评价代码质量时,可以使用静态代码分析工具来自动检查代码中的潜在问题,如语法错误、未使用的变量、潜在的空指针异常等。此外,代码审查也是一个重要的环节,通过团队成员的互相审查可以发现潜在的问题和改进点。

        最终,代码质量的评价是一个主观与客观相结合的过程,需要综合考虑上述多个方面,并根据项目的具体需求和团队的实际情况进行判断和评估。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/771014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux-进程控制(进程创建、进程终止、进程等待)

一、进程创建 1.1 fork函数介绍 在命令行下我们可以通过 ./ exe文件 来创建一个进程,通过fork函数,我们可以通过代码的形式从一个进程中创建一个进程,新进程为子进程,原进程为父进程,子进程在创建时,会与…

教育建筑智慧能源管理平台解决方案【新型电力系统下的绿色校园能源管理平台】

一、行业特点 1.建筑类型多:集教学、科研、生活于一体,占地面积大,建筑类型多,功能划分复杂。 2.供电可靠性要求高:教育建筑中的高层建筑、图书馆、实验楼等特级和一级负荷比较多,一旦发生故障会危及生命…

STM32 ESP8266模块的曲折探索

这是本文的配套资料,最终工程请参考 新_ESP8266资料\stm32f103成功移植的项目 【免费】stm32f103c8t6esp8266资料资源-CSDN文库 一、等到了ready 产品参数 我使用的是ai-thinker的esp8266-01s,以下为产品规格书 引脚定义: 依据引脚定义&…

ssh -p 2222怎么进docker容器

要通过SSH和端口2222进入Docker容器,您需要确保容器内已经安装并运行了SSH服务器,并且已经将宿主机的2222端口映射到容器的SSH端口(通常为22)。以下是一般的步骤: 1、启动容器时映射端口: 当您启动容器时…

android studio忽略文件

右键文件,然后忽略,就不会出现在commit里面了 然后提交忽略文件即可

Linux查询日志常用命令整理

Linux查询日志常用命令整理 1. 实时查看日志2. 查看历史日志的最后几行3. 根据关键词过滤日志4. 查询指定路径下的所有日志文件5. 当日志文件过大时,查看开头部分6. 筛选出指定时间范围内的日志7. 分页查看日志8. 将查询到的日志输出到另一个文件9. 查看过去某一时间…

如何在VS Code上搭建 C/C++开发环境

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、什么是VScode VScode(Visual Studio Code)是一款由微软开发的免费开源的轻量级代码编辑器。它…

AI绘画自动生成器有哪些?

AI绘画自动生成器近年来发展迅速,以下是一些知名的和受欢迎的AI绘画工具: DALL-E2 - 由OpenAI开发,可以依据文本描述生成高度逼真的图像。Deep Dream Generator - 使用深度学习技术对上传的图片进行艺术化处理。Artbreeder - 提供图像合成和…

鸿蒙 ohpm 的异常报错

解压安装 ohpm , 进入 command-line-tools/ohpm/bin 目录执行 ohpm -v , 一直提示未初始化异常:ERROR: ohpm has not been initialized yet. Execute the init script to initialize it first. google搜索发现都是让配置环境变量、执行init脚本,尝试后…

Python操作Sqlite的简单封装

文章目录 一、安装依赖二、配置文件三、实现类 一、安装依赖 pip install numpy二、配置文件 utils.config.py ############### 233 SQLITE Configuration ############### SQLITE_PATH ./mysqlite.db三、实现类 utils.PostGreOp.py # encoding: utf-8import json import …

如何成功将自己开发的APP上架到应用商店

随着移动应用市场的蓬勃发展,开发一款优秀的APP已成为许多企业和个人的首要选择。然而,成功上架并有效推广APP至关重要。本文将逐步介绍完整的上架流程,包括准备所需材料、注册开发者账户、进行APP备案、提交审核以及上架成功后的推广和维护。…

maya 重定向 pycharm运行

目录 maya sdk下载: 添加sdk 依赖库: pycharm连接 maya 测试ok maya重定向脚本 插

电子商务营销中大数据分析|电商大数据采集API接口的应用

随着经济的不断发展,网络信息技术不断加强,电子商务和大数据的蓬勃发展极大地方便了人们的生活。本文章主要阐述大数据分析与电商营销的含义、大数据分析在电子商务营销中的应用,以及该应用的作用和存在哪些不足及解决方法。探究大数据分析在…

【MATLAB源码-第14期】基于matlab的2ASK的误码率BER仿真以及原信号调制信号解调信号波形展示。

操作环境: MATLAB 2022a 1、算法描述 幅度偏移调制,又称幅移键控,幅度键移(英语:Amplitude-shift keying,ASK)是通过载波的幅度变化来表示数字信号的一种幅度调制方式。在一个ASK系统中&…

Web日志分析

一 、HTTP基础 1. HTTP报文格式解析 HTTP请求报文 HTTP请求包括3部分,分别是请求行、请求头和请求正文。 Windows NT 10.0表示操作系统内核版本号,Windows XP内核号是NT 5.1或NT 5.2(64位操作系统),Windows Vista的内核版本号是…

mybatisPlus动态sql语句 ${ew.customSqlSegment}

1.Mapper层 List<SmsSendTaskVO> queryList(Param("ew")Wrapper wrapper, DataScope dataScope); 2.sql语句 Select(" select t.submit_num,t.sms_charge_num ${ew.customSqlSegment}”) ${ew.customSqlSegment}是MyBatis Plus提供的动态SQL语句拼接功能…

Nebula Graph-06-NebulaGraph Java 使用 和SpringBoot集成Nebula Graph

前言 系列文章&#xff1a; Nebula Graph-01-Nebula Graph简介和安装以及客户端连接 Nebula Graph-02-NebulaGraph高阶配置、用户管理、日志 Nebula Graph-03-NebulaGraph Studio-可视化web工具安装和使用 Nebula Graph-04-NebulaGraph nGQL的介绍和使用 Nebula Graph-05-Nebu…

【干货】Apache DolphinScheduler2.0升级3.0版本方案

升级背景 因项目需要使用数据质量模块功能&#xff0c;可以为数仓提供良好的数据质量监控功能。故要对已有2.0版本升级到3.0版本以上&#xff0c;此次选择测试了3.0.1 和 3.1.1 两个版本&#xff0c;对进行同数据等任务调度暂停等操作测试&#xff0c;最后选择3.0.1 版本 原因…

看漫画学Python:有趣好玩

书籍介绍 Python是一门既简单又强大的编程语言&#xff0c;被广泛应用于数据分析、大数据、网络爬虫、自动化运维、科学计算和人工智能等领域。Python也越来越重要&#xff0c;成为国家计算机等级考试科目&#xff0c;某些中小学也开设了Python编程课程。本书秉承有趣、有料、…

【linux网络(一)】初识网络, 理解四层网络模型

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux网络 1. 前言2. 初识网络…