改善代码质量,试试这10种方法

news2024/11/23 19:15:30

那么,什么是高质量的代码?如何才能写出高质量的代码?为什么有的程序员工作 5年,写出来的代码质量还不如 3年的程序员?今天我们就来聊一聊。

1. 什么是高质量代码

代码的“好”与“坏”是一个相对的描述,因此,高质量代码也是一个很宽泛的概念,很难给它下一个精准的定义,但是,我们可以结合日常的开发工作经验,给出几个常见的衡量维度:

1. 可读性

高质量的代码首先需要具备可读性,我们编写的代码除了需要让机器能编译运行之外,更需要让程序员读懂,因为只有程序员读懂了它,才能更好地修 bug,添加新功能,做后期维护等等。

可能有小伙伴会说,Spring的源码很难读懂,因此它不具备可读性,这种理解是错误的,Spring框架是 Java生态中比较优秀的开源代码,读不懂是因为“内功”不够,本文的可读性是指代码命名是否规范,注释是否合理,分层是否清晰以及是否具备高内聚低耦合等特性。

2. 可维护性

现实工作中,很难遇见一次性代码(开发部署完之后再也不需要迭代),大部分情况都需要在一个模块上不断地迭代新功能和新代码,因此,高质量的代码必须具备可维护性。

可维护性反馈到代码上,可以通俗地表达成:bug能修改,老代码改得动,新功能可添加。而这些更改花费的代价就体现了可维护的难和易,比如:改动是否会增加大量的新 bug,改动对现有的逻辑的破坏性有多大,或者说改动的时间是否会很长。

3. 可扩展性

在代码设计 SOLID 中有一个很重要的原则就是开闭原则,要求代码需要 “对修改关闭,对扩展开放”,因此,高质量的代码需要具备可扩展性。在应对业务迭代时,开发者需要多关注代码能否用最小的改动来适配新的功能。

4. 可复用性

在日常开发中,尽量不重复造轮子,具体到代码上,不应该出现大量重复的代码,代码应该保持简洁,重复的代码可以抽离出来,实现代码复用。因此,可复用性也是衡量高质量代码的一个重要标准。

5. 可测试性

单测是开发人员保证代码质量的一个重要方法,因此,编写的代码是否具备可测试性,也是衡量代码高质量的一个标准。如果编写的代码很难写单元测试,那是否意味着代码设计存在很大的问题?

在分析了高质量代码的几个常用衡量维度之后,我们可以总结:所谓高质量的代码,其实就是衡量能否写出可读性好,易维护,易扩展,复用性高,可测试的代码。

接下来提供 10种高效提升代码质量的方法。

2. 提升代码质量方法

1 规范命名

众所周知,一个好的名字可以使人受用一生,对于代码也是如此,好的命名可以帮助读者更好地理解代码的功能。

对于计算机科班出身的小伙伴,或许在大学的第一节编程课就被强调:代码命名要简明扼要并且见名知意,不要使用拼音,不要使用非公认的缩写等等,下面为代码命名的几点建议:

  • 使用常见的英文单词,不使用拼音

代码的命名,应该尽量使用常见的英文单词,这样对于大部分人来说能够知道其意图。不要使用拼音命名,在软件开发领域,英文是主要的编程语言和命名规范。使用拼音给代码命名违反了行业的惯例和标准而且可读性差。

  • 使用公认的缩写,否则使用全称

有时候,为了简化命名,会使用缩写,但是这些缩写一定要是业内大家公认的,比如:Impl 指代 Implement, str 指代 String,num 指代 number,del 指代 delete。

  • 使用和团队一致的命名风格

现在的开发大部分是团队合作,因此,代码命名应该在团队内部保持一致,比如:和数据库交互的 Reporitory层,一般都是 CRUD方法的封装,如果团队使用 selectXXX 代表查询,我们就不要使用getXXX 或者 queryXXX,这样检索查询的方法时,可以根据select定位,同理,对于添加数据是使用 addXXX 还是 saveXXX 或者 insertXXX,也需要保持一种方式。

  • 命名不要太长
  • 命名要尽量的简短,而且能准确的传达意思,如果需要使用长命名,建议不要超过5个单词。

温馨建议:如果你在日常工作中对于命名拿不准时,可以给身边的同事参考,看看他们对该命名是否和你的本意是一致,这样也能帮助你更好的去命名。

2 巧用注释

命名可以帮助读者从字面上了解代码的功能,但无法传达代码更多细节,因此,需要借助注释来完成这部分功能。喜欢查看源码的小伙伴应该可以发现,在 JDK,Spring等这些优秀的开源框架的源码中,类,方法甚至变量,几乎都有相应的注释,而我们在使用某个功能时,最直接的方式往往是通过官方提供的注释来了解其功能,因此,注释的重要性可想而知。

因此,注释是命名的补充和增强。

注释需要写什么内容呢?这里以 java.util.Collections 为例, 如下图:

通过 JDK 的 Collections源码注释可以看出:注释的内容大概包含 5部分信息:what, why, how, time, authors 即是什么?为什么?怎样做?时间 和 作者。我们可以根据需要灵活的搭配来添加注释。需要注意的,注释也需要简明扼要,尽量使用一些提炼,解释和总结性的语句,切勿长篇大论。

3 代码风格

一个好的代码风格可以让代码看起来很清爽,降低代码阅读的复杂度。代码风格主要体现在以下几点:左括号风格,代码缩进,空行,超长行,魔数,方法代码过多,方法参数过多

  • 左括号风格
  • 在代码行尾还是换行使用左括号,这个根据个人习惯,不过团队合作要求保持一种风格。
  • 代码缩进
  • 代码编写时,为了美观,一般都不会顶格,需要缩进,因此常见的缩进有 两格缩进和四格缩进,选择哪一种也是根据个人习惯,不过团队合作要求保持一种风格。
  • 空行
  • 在方法内部,我们可以使用空行,将逻辑独立的代码块区分,这样,一方面可以更方便的阅读方法实现,另一方面,当独立的代码块代码量增多时,可以考虑将代码块抽离成新的方法。
  • 超长行
  • 每行的代码量不要太长,通常建议电脑一屏的宽度为准,如果超过一屏,建议换行。
  • 魔数
  • 在代码编写时,不要出现魔数,我们要善于使用常量去定义这些魔数,增加代码的可读性。
  • 方法代码过多
  • 每个方法中的代码量不要太多,因为代码太多会增加方法阅读的复杂度,通常建议电脑一屏的高度为准,超过了就要考虑能否再抽离出新方法。
  • 方法参数过多
  • 编写方法的时候,通常都会定义入参,一般建议入参的个数不要超过5个,如果再多就需要考虑封装对象来传递参数。

以上代码风格如果是团队合作,最好是保持一致。更多代码规范 推荐《代码整洁之道》和《阿里巴巴开发手册》

4 快速短路

如下的伪代码,当 user == null时,可以通过 return快速短路返回,去除多余的 esle 语句。因此,在日常业务开发中,遇到类似的情况,一定要做到快速短路,切莫使用大量嵌套。比如 if-esle 语句可以使用 return 快速短路;对于 for 循环可以使用 break,continue,return等提前跳出,减少不必要的遍历;

public User getUser(String id) { // get by id User user = getById(id);
 if(user == null){  
     return null; 
 } else {   
     // else 逻辑 
 }  
 // 优化成 
 if(user == null){  
     return null;
 } 
 // else 逻辑 

5 SOLID原则

在类或者方法的设计上要尽量遵守 SOLID原则,SOLID原则是业内一个比较的原则,关于 SOLID原则可以参考小编以往的文章:优雅代码,从 SOLID 开始

6 设计模式

设计模式在代码中的使用是一个比较高阶的能力体现,巧用设计模式,可以大大提高代码的可维护性、可扩展性和可重用性等功能,在很多开源的框架上都有设计模式的体现,比如:Spring 中的单例模式(Single Pattern)工厂模式(Factory Pattern),代理模式(Proxy Pattern),适配器模式(Adapter Pattern),模板模式(Template Pattern),观察者模式(Observer Pattern)等等。

如果你对设计模式不是很熟悉,推荐书籍 Erich Gamma 的《设计模式》,另外,JDK 和 Spring框架也是一个很好的学习资料,可以对照着源码中设计模式的代码,加强对设计模式的理解,然后可以尝试着在日常开发中去使用某些设计模式。

7 单元测试

单元测试是开发人员保证代码质量最直接的方式,但现实工作中却被很多人忽略,有的借故业务开发忙,没有把时间写单测,因此把测试功能全部丢给测试人员,有的是不如何写单测,关于单元测试,可以参阅小编以往文章:TDD,什么是 测试驱动开发?

**8 数据结构
**

有人说 程序 = 数据结构 + 算法,足以看出数据结构和算法的重要性,作为 Java程序员,我们经常使用的 HashMap, List, Set, String 等都是 Java 语言对数据结构的一种友好封装,关于数据结构,可以参阅小编以往文章:数据库,你必须掌握的8种数据结构! 数据结构之美:为什么 MySQL 选择 B+树做索引?

在实际工作中,很多人面对的工作绝大多数是业务开发,所以处理数据肯定离不开数据结构,建议平时多研究 JDK 的源码,比如:Map,List 等常用的数据结构的底层实现原理,这样在使用时才能得心应手应手。

9 算法

近些年,算法在技术面试中的比重越来越大,特别是在一些知名的互联网公司面试,如果代码中能够合理地使用算法,将事半功倍。需要说明的是,在日常的业务开发中,手写算法的概率比较低,一般会使用三方框架,比如:Google Guava中的限流算法。

对于算法,似乎没有很好的捷径,小编的建议是:经常去算法网站上刷题,一方面让算法能力处于随时可以面试的状态,一方面通过大量的算法实现量变到质变,掌握算法的精髓。

10 重构

重构是代码迭代中一直会存在的行为,当发现代码有 Bad Smell “坏味道”时,得考虑代码是否需要重构。重构,一般分为小重构和大重构,小重构通常是指工作量小,时间可控(比如时间不超过 2个工作日),甚至不需要测试参与。大重构是指时间周期比较大,对代码的改造比较大,一般需要整体设计,然后分阶段进行。关于代码重构,可以参考微服务作者 Martinfowler 的博客:
martinfowler.com/books/refac… 或者 Martinfowler 的书籍:《重构,改善既有代码的设计》第二版,《重构与模式》《修改代码的艺术》

3. 总结

本文分析了高质量代码的几个衡量维度:

  1. 可读性
  2. 可维护性
  3. 可扩展性
  4. 可复用性
  5. 可测试性

在编写代码时,应该多关注上面几个因素,一开始可以刻意练习,然后慢慢变成一种习惯,这样编写的代码质量应该不会太差。

接着我们介绍了提升代码质量的 10种常用方法:

  1. 规范命名
  2. 巧用注释
  3. 代码风格
  4. 快速短路
  5. 单元测试
  6. SOLID原则
  7. 设计模式
  8. 数据结构
  9. 算法
  10. 重构

前 4种方法更多体现在代码的“形”上,体现了程序员对代码细节的把握,而后 6种方法则更多体现了代码的“神”,体现了程序员基本功和能力。

根据小编多年的工作经验,前 4种方法是最简单,提升代码质量最见效的方法,它们几乎和能力和工作年限无关,完全在于程序员能否扣住细节,如果能够在这 4个方法上多花点功夫,编写的代码已经可以甩很多人一条街了。

对于后 6种方法,是开发人员内功的体现,它要求的是一个长期的积累和修炼过程,是开发人员能力差距的最好体现,所以,通过这 6点可以很好地定位某个程序员的编程段位。建议平时多阅读一些业内大牛的经典书籍。

4. 个人心得

工作中,经常会遇见一些工作 5年的程序员,写的代码质量却远不如 3年的程序员,为什么?小编觉得有以下几个原因:

  1. 职业规划不清晰

对于他们来说,大部分都没有清晰职业规划,没有方向自然就没有努力的目标,没有目标就很容进入日复一日循环重复工作的僵局。

  1. 代码能用就行

工作中小编也和一些人讨论过,他们对代码的态度是:没有必要这么苛刻,能用就行。如果是刚进入社会工作,或许还能理解,如果已经工作 3年以上,还是这种想法,竞争力在哪里?作为程序员,代码质量不就是最好的武器吗?

  1. 编程不是兴趣

对于很多人来说,选择编程并不是因为喜欢而是觉得它的工资相对其他行业来说会高一些。众所周知,兴趣是最好的老师,如果长年累月的干一件没有兴趣的事,能干好吗?

  1. 外部诱惑太多

游戏,短视频等外部诱惑太多,一玩停不下来,工作之余的大部分时间都被这些“精神鸦片”消耗殆尽。

因为篇幅有限,不可能把每个细节点都讲清楚,分享一个小编多年来一直在践行的学习方法:持续学习,多听,多看,catch 他人优秀的 idea,然后不断地丰富和领会该 idea,最终形成自己的方法论。丰富和领会的过程就在不断地强大自己,相信长年累月的积累,终有一天你也可以写出让人赏心悦目的高质量代码。

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

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

相关文章

WEB渗透—PHP反序列化(一)

Web渗透—PHP反序列化 课程学习分享(课程非本人制作,仅提供学习分享) 靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场 课程地址:PHP反序列化漏洞学习_哔哩…

Vue3-16-【v-model】 表单数据绑定

作用描述 v-model 指令,实现了 表单输入组件的值 与 js 中的变量的值的绑定关系。 当我们在页面上执行输入动作时,js中变量的值也会同步发生变化。表单不仅仅局限于输入框,其他的如 : 单选按钮,复选框,下拉…

用AI画个女朋友回家过年,1行Python代码,免费实现

#这才是真功夫# 大家好,这里是程序员晚枫,全网同名。 马上过年了,还是单身的举个爪! 今年GPT系列的产品非常火爆,今天给大家分享一下,如何免费用AI代码画1个女朋友。👇 直接上代码 大家学习 或 …

【代码随想录】刷题笔记Day35

前言 日常学习,抵触心理5%;毫无指示的干活,抵触心理95% 122. 买卖股票的最佳时机 II - 力扣(LeetCode) 把整体利润拆分为每次利润,只要积上涨的就可以,so easy class Solution { public:int …

Android codec2 视频框架之编码输出内存管理

文章目录 pool的创建pool 中申请内存buffer 从service传递到clientC2buffer转换为MediaCodecBuffer编码 输出C2buffer的生命周期 buffer在框架中的流动流程,从buffer的申请、填充数据到binder中传递、转换为应用层数据、从应用层释放。 围绕以下的方面:…

业务代码-整合框架-存储-缓存常见错误详解一

一. java空指针和异常: 1.什么是空指针异常(java.lang.NullPointException): 1.1常见的空指针异常案例: public class WhatIsNpe {public static class User {private String name;private String[] address;public void print…

【C++11】右值引用与移动语义

一.左值与右值 左值:可以取地址的表示数据的表达式,左值可以出现在赋值符号左边 右值:不能取地址的表示数据的表达式,右值不能出现在赋值符号左边 int fun() {return 0; } int main() {int a 0;//a->左值const int b 1;//b-&…

Java 入门第四篇 集合

Java 入门第四篇 集合 一,什么是集合 在Java中,集合(Collection)是一种用于存储和操作一组对象的容器类。它提供了一系列的方法和功能,用于方便地管理和操作对象的集合。集合框架是Java中非常重要和常用的一部分&…

C++进阶篇9---类型转换

C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与 接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型 转换和…

参数学习——糖果问题(人工智能期末复习)

之前看了好久都不知道这题咋写,后来看了这篇机器智能-高频问题:糖果问题,大概看明白了,其实主要围绕着这两个公式 光看公式也看不懂,还是要结合题目来 己知有草莓味和酸橙味两种类型的糖果,分别放入5种不同…

深入了解—C++11特性

目录 一、 C11简介 二、初始化列表 2.1 C98中{}的初始化问题 2.2 内置类型的列表初始化 2.3 自定义类型的列表初始化 2.3.1. 标准库支持单个对象的列表初始化 2.3.2. 多个对象的列表初始化 三、变量类型推导 3.1 为什么需要类型推导 3.2 decltype类型推导 3.2.1. 推…

SIM初始化流程

ATR ATR(Answer To Reset):复位应答信号,有SIM卡传输给终端,包括SIM卡自身的一些信息,比如支持的传输速率,传输模式等。 SIM卡的ATR代表"Answer to Reset",即复位响应。当SIM卡被插入设备中时…

Java的String类常用方法 |StringBuilder和StringBuffer

文章目录 String类常用方法字符串查找转化字符串替换字符串拆分字符串截取其他操作方法 字符串的不可变性StringBuilder和StringBufferStringBuilder的介绍面试题 String类常用方法 字符串查找 方法功能char charAt(int index)返回index位置上字符,如果index为负数…

深度解读分布式事务Seata入门到实践 -尚马教育

目录 一、事务的回顾1、什么是事务2、事务的特性3、事务的隔离级别4、事务的分类 二、分布式事务1、什么是分布式事务2、分布式事务产生的背景3、分布式事务产生的场景4、分布式事务理论4.1 CAP理论4.2 Base理论 5、分布式事务的解决方案 三、强一致性介绍3.1 基本理解3.2 DTP模…

arm-none-eabi-gcc not find

解决办法:安装:gcc-arm-none-eabi sudo apt install gcc-arm-none-eabi; 如果上边解决问题了就不用管了,如果解决不了,加上下面这句试试运气: $ sudo apt-get install lsb-core看吧方正我是运气还不错,感…

环境搭建及源码运行_java环境搭建_mysql安装

1、介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一 1、源码中涉及到的表:mysql 表:订单、意见反馈、用户基础信息、商品、购物车等表 2、订单属于…

Qt/C++视频监控安卓版/多通道显示视频画面/录像存储/视频播放安卓版/ffmpeg安卓

一、前言 随着监控行业的发展,越来越多的用户场景是需要在手机上查看监控,而之前主要的监控系统都是在PC端,毕竟PC端屏幕大,能够看到的画面多,解码性能也强劲。早期的手机估计性能弱鸡,而现在的手机性能不…

自动反冲洗过滤器直通式工作原理介绍和附反冲洗原理图动画讲解

​ 1:自动反冲洗过滤器直通式设备介绍 自动反冲洗过滤器是一种先进、高效且易操作的精密设备,广泛应用于冶金、化工、石油、造纸、医药、食品、采矿、电力、城市给水等领域。 在过滤过程中,待过滤的水由进水口进入过滤器机体,流…

Java版工程行业管理系统源码-专业的工程管理软件-提供一站式服务—鸿鹄工程管理系统

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 项目背景 随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管理的提…

Python(七)操作JSON

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…