如何评价代码质量

设计模式专栏: 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.总结

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

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

  • 28
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
当涉及到图像质量评价时,MATLAB是一个非常强大的工具。以下是一些常用的MATLAB代码库和函数,用于图像质量评价: 1. Image Quality Assessment Toolbox (IQAT): IQAT是一个广泛使用的MATLAB工具箱,用于图像质量评价。它提供了多种图像质量评价算法的实现,包括SSIM、PSNR、MSE等。你可以在MATLAB File Exchange上找到并下载该工具箱。 2. PSNR(峰值信噪比)计算: PSNR是一种常用的图像质量评价指标,用于衡量原始图像与压缩/失真图像之间的差异。以下是一个简单的MATLAB代码示例,用于计算两个图像之间的PSNR值: ```matlab function psnr_value = calculate_psnr(original_image, distorted_image) mse = mean((original_image(:) - distorted_image(:)).^2); max_value = max(original_image(:)); psnr_value = 10 * log10((max_value^2) / mse); end ``` 3. SSIM(结构相似性)计算: SSIM是一种衡量图像质量的指标,考虑了亮度、对比度和结构等方面的信息。以下是一个简单的MATLAB代码示例,用于计算两个图像之间的SSIM值: ```matlab function ssim_value = calculate_ssim(original_image, distorted_image) k1 = 0.01; k2 = 0.03; L = 255; % 图像的动态范围 C1 = (k1 * L)^2; C2 = (k2 * L)^2; mu1 = mean2(original_image); mu2 = mean2(distorted_image); sigma1 = std2(original_image); sigma2 = std2(distorted_image); sigma12 = std2(original_image .* distorted_image); numerator = (2 * mu1 * mu2 + C1) * (2 * sigma12 + C2); denominator = (mu1^2 + mu2^2 + C1) * (sigma1^2 + sigma2^2 + C2); ssim_value = numerator / denominator; end ``` 这些是一些常用的MATLAB代码示例,用于图像质量评价。你可以根据具体的需求选择适合的评价指标和算法,并在MATLAB中实现相应的代码。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值