改善代码质量的20条编程规范
改善代码质量的20条编程规范
Ivanqhz
于 2024-10-23 10:44:03 发布
阅读量929
收藏
8
点赞数
10
CC 4.0 BY-SA版权
文章标签:
设计模式
java
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40398522/article/details/143178048
命名
命名多长最合适?
命名的一个原则就是以能准确达意为目标在足够表达其含义的情况下,命名当然是越短越好。但是,大部分情况下,短的命名都没有长的命名更能达意
利用上下文简化命名
在 User 类这样一个上下文中,我们没有在成员变量的命名中重复添加“user”这样一个前缀单词而是直接命名为 name、password、avatarUrl在使用这些属性时候,我们能借助对象这样一个上下文,表意也足够明确
命名要可读、可搜索
“可读”,指的是不要用一些特别生僻、难发音的英文单词来命名“可搜索”,可以通过关键词联想的方式来自动补全和搜索,比如有统一的命名前缀,比如 “queryXXX”, “insertXXX”
如何命名接口和抽象类?
对于接口的命名,一般有两种比较常见的方式一种是加前缀“I”,表示一个 Interface
比如 IUserService,对应的实现类命名为 UserService
另一种是不加前缀,比如 UserService,对应的实现类加后缀“Impl”
比如 UserServiceImpl
注释
注释到底该写什么?
注释的内容主要包含这样三个方面:做什么、为什么、怎么做注释比代码承载的信息更多
命名的主要目的是解释“做什么”比如,void increaseWalletAvailableBalance(BigDecimal amount) 表明这个函数用来增加钱包的可用余额boolean isValidatedPassword 表明这个变量用来标识是否是合法密码但是,对于类来说,包含的信息比较多,一个简单的命名就不够全面详尽了这个时候,在注释中写明“做什么”就合情合理了
注释起到总结性作用、文档的作用
代码之下无秘密阅读代码可以明确地知道代码是“怎么做”的,也就是知道代码是如何实现的,那注释中是不是就不用写“怎么做”了?实际上也可以写在注释中,关于具体的代码实现思路,我们可以写一些总结性的说明、特殊情况的说明这样能够让阅读代码的人通过注释就能大概了解代码的实现思路,阅读起来就会更加容易
一些总结性注释能让代码结构更清晰
对于逻辑比较复杂的代码或者比较长的函数,如果不好提炼、不好拆分成小的函数调用那我们可以借助总结性的注释来让代码结构更清晰、更有条理
注释是不是越多越好?
注释太多和太少都有问题太多,有可能意味着代码写得不够可读,需要写很多注释来补充类和函数一定要写注释,而且要写得尽可能全面、详细而函数内部的注释要相对少一些,一般都是靠好的命名、提炼函数、解释性变量、总结性注释来提高代码的可读性
类、函数多大才合适?
类中的代码行数不超过200行、函数或属性不超过10个还是有一个间接的判断标准
当一个类的代码读起来让你感觉头大了,实现某个功能时不知道该用哪个函数了想用哪个函数翻半天都找不到了,只用到一个小功能要引入整个类(类中包含很多无关此功能实现的函数)的时候这就说明类的行数过多了
一行代码多长最合适?
在Google Java Style Guide文档中,一行代码最长限制为 100 个字符总体上来讲我们要遵循的一个原则是:一行代码最长不能超过 IDE 显示的宽度需要滚动鼠标才能查看一行的全部代码,显然不利于代码的阅读
善用空行分割单元块
对于比较长的函数,如果逻辑上可以分为几个独立的代码块,在不方便将这些独立的代码块抽取成小函数的情况下为了让逻辑更加清晰,除了上一节课中提到的用总结性注释的方法之外,我们还可以使用空行来分割各个代码块在类的成员变量与函数之间、静态成员变量与普通成员变量之间、各函数之间、甚至各成员变量之间,我们都可以通过添加空行的方式让这些不同模块的代码之间,界限更加明确写代码就类似写文章,善于应用空行,可以让代码的整体结构看起来更加有清晰、有条理
四格缩进还是两格缩进?
只要项目内部能够统一就行了当然,还有一个选择的标准,那就是跟业内推荐的风格统一、跟著名开源项目统一
大括号是否要另起一行?
要团队统一、业内统一、跟开源项目看齐就好了
类中成员的排列顺序
在类中,成员变量排在函数的前面成员变量之间或函数之间,都是按照先静态(静态函数或静态成员变量)、后普通(非静态函数或非静态成员变量)的方式来排列的除此之外,成员变量之间或函数之间,还会按照作用域范围从大到小的顺序来排列先写 public 成员变量或函数,然后是 protected 的,最后是 private 的
把代码分割成更小的单元块
大部分人阅读代码的习惯都是,先看整体再看细节所以,我们要有模块化和抽象思维,善于将大块的复杂逻辑提炼成类或者函数,屏蔽掉细节,让阅读代码的人不至于迷失在细节中,这样能极大地提高代码的可读性不过,只有代码逻辑比较复杂的时候,我们其实才建议提炼类或者函数。毕竟如果提炼出的函数只包含两三行代码,在阅读代码的时候,还得跳过去看一下,这样反倒增加了阅读成本
避免函数参数过多
函数包含 3、4 个参数的时候还是能接受的,大于等于 5 个的时候,我们就觉得参数有点过多了,会影响到代码的可读性,使用起来也不方便对参数过多的情况,一般有 2 种处理方法
考虑函数是否职责单一,是否能通过拆分成多个函数的方式来减少参数public User getUser(String username, String telephone, String email);
// 拆分成多个函数
public User getUserByUsername(String username);
public User getUserByTelephone(String telephone);
public User getUserByEmail(String email);
将函数的参数封装成对象public void postBlog(String title, String summary, String keywords, String content, String category, long authorId);
// 将参数封装成对象
public class Blog {
private String title;
private String summary;
private String keywords;
private Strint content;
private String category;
private long authorId;
}
public void postBlog(Blog blog);
勿用函数参数来控制逻辑
布尔类型作为标识参数
不要在函数中使用布尔类型的标识参数来控制内部逻辑,true 的时候走这块逻辑,false 的时候走另一块逻辑这明显违背了单一职责原则和接口隔离原则我建议将其拆成两个函数,可读性上也要更好public void buyCourse(long userId, long courseId, boolean isVip);
// 将其拆分成两个函数
public void buyCourse(long userId, long courseId);
public void buyCourseForVip(long userId, long courseId);
// 拆分成两个函数的调用方式
boolean isVip = false;
//...省略其他逻辑...
if (isVip) {
buyCourseForVip(userId, courseId);
} else {
buyCourse(userId, courseId);
}
// 保留标识参数的调用方式更加简洁
boolean isVip = false;
//...省略其他逻辑...
buyCourse(userId, courseId, isVip);
根据参数是否为 null
public List
if (startDate != null && endDate != null) {
// 查询两个时间区间的transactions
}
if (startDate != null && endDate == null) {
// 查询startDate之后的所有transactions
}
if (startDate == null && endDate != null) {
// 查询endDate之前的所有transactions
}
if (startDate == null && endDate == null) {
// 查询所有的transactions
}
}
// 拆分成多个public函数,更加清晰、易用
public List
return selectTransactions(userId, startDate, endDate);
}
public List
return selectTransactions(userId, startDate, null);
}
public List
return selectTransactions(userId, null, endDate);
}
public List
return selectTransactions(userId, null, null);
}
private List
// ...
}
针对这种情况,我们也应该将其拆分成多个函数拆分之后的函数职责更明确,不容易用错
函数设计要职责单一
public boolean checkUserIfExisting(String telephone, String username, String email) {
if (!StringUtils.isBlank(telephone)) {
User user = userRepo.selectUserByTelephone(telephone);
return user != null;
}
if (!StringUtils.isBlank(username)) {
User user = userRepo.selectUserByUsername(username);
return user != null;
}
if (!StringUtils.isBlank(email)) {
User user = userRepo.selectUserByEmail(email);
return user != null;
}
return false;
}
// 拆分成三个函数
public boolean checkUserIfExistingByTelephone(String telephone);
public boolean checkUserIfExistingByUsername(String username);
public boolean checkUserIfExistingByEmail(String email);
对于函数的设计来说,更要满足单一职责原则相对于类和模块,函数的粒度比较小,代码行数少所以在应用单一职责原则的时候,没有像应用到类或者模块那样模棱两可,能多单一就多单一
移除过深的嵌套层次
定义
代码嵌套层次过深往往是因为 if-else、switch-case、for 循环过度嵌套导致的个人建议,嵌套最好不超过两层,超过两层之后就要思考一下是否可以减少嵌套过深的嵌套本身理解起来就比较费劲嵌套过深很容易因为代码多次缩进,导致嵌套内部的语句超过一行的长度而折成两行,影响代码的整洁
去掉多余的 if 或 else 语句
// 示例一
public double caculateTotalAmount(List
if (orders == null || orders.isEmpty()) {
return 0.0;
} else { // 此处的else可以去掉
double amount = 0.0;
for (Order order : orders) {
if (order != null) {
amount += (order.getCount() * order.getPrice());
}
}
return amount;
}
}
// 示例二
public List
List
if (strList != null && substr != null) {
for (String str : strList) {
if (str != null) { // 跟下面的if语句可以合并在一起
if (str.contains(substr)) {
matchedStrings.add(str);
}
}
}
}
return matchedStrings;
}
使用编程语言提供的 continue、break、return 关键字,提前退出嵌套
// 重构前的代码
public List
List
if (strList != null && substr != null){
for (String str : strList) {
if (str != null && str.contains(substr)) {
matchedStrings.add(str);
// 此处还有10行代码...
}
}
}
return matchedStrings;
}
// 重构后的代码:使用continue提前退出
public List
List
if (strList != null && substr != null){
for (String str : strList) {
if (str == null || !str.contains(substr)) {
continue;
}
matchedStrings.add(str);
// 此处还有10行代码...
}
}
return matchedStrings;
}
调整执行顺序来减少嵌套
// 重构前的代码
public List
List
if (strList != null && substr != null) {
for (String str : strList) {
if (str != null) {
if (str.contains(substr)) {
matchedStrings.add(str);
}
}
}
}
return matchedStrings;
}
// 重构后的代码:先执行判空逻辑,再执行正常逻辑
public List
if (strList == null || substr == null) { //先判空
return Collections.emptyList();
}
List
for (String str : strList) {
if (str != null) {
if (str.contains(substr)) {
matchedStrings.add(str);
}
}
}
return matchedStrings;
}
将部分嵌套逻辑封装成函数调用,以此来减少嵌套
// 重构前的代码
public List
if (passwords == null || passwords.isEmpty()) {
return Collections.emptyList();
}
List
for (String password : passwords) {
if (password == null) {
continue;
}
if (password.length() < 8) {
// ...
} else {
// ...
}
}
return passwordsWithSalt;
}
// 重构后的代码:将部分逻辑抽成函数
public List
if (passwords == null || passwords.isEmpty()) {
return Collections.emptyList();
}
List
for (String password : passwords) {
if (password == null) {
continue;
}
passwordsWithSalt.add(appendSalt(password));
}
return passwordsWithSalt;
}
private String appendSalt(String password) {
String passwordWithSalt = password;
if (password.length() < 8) {
// ...
} else {
// ...
}
return passwordWithSalt;
}
学会使用解释性变量
常量取代魔法数字
public double CalculateCircularArea(double radius) {
return (3.1415) * radius * radius;
}
// 常量替代魔法数字
public static final Double PI = 3.1415;
public double CalculateCircularArea(double radius) {
return PI * radius * radius;
}
使用解释性变量来解释复杂表达式
if (date.after(SUMMER_START) && date.before(SUMMER_END)) {
// ...
} else {
// ...
}
// 引入解释性变量后逻辑更加清晰
boolean isSummer = date.after(SUMMER_START)&&date.before(SUMMER_END);
if (isSummer) {
// ...
} else {
// ...
}
确定要放弃本次机会?
福利倒计时
:
:
立减 ¥
普通VIP年卡可用
立即使用
Ivanqhz
关注
关注
10
点赞
踩
8
收藏
觉得还不错?
一键收藏
知道了
0
评论
分享
复制链接
分享到 QQ
分享到新浪微博
扫一扫
举报
举报
程序编写规范
jiawei31191的博客
04-12
1056
C#是一种流行的编程语言,被广泛用于Windows应用程序的开发。为了提高代码的可读性和可维护性,编写规范非常重要。本文将介绍C#程序编写规范,以帮助开发人员编写高质量的代码。
参与评论
您还未登录,请先
登录
后发表或查看评论
Java编码规范
qq_24868375的博客
08-24
414
Java编码规范
代码质量-checkStyle检查代码规范
03-19
NULL
博文链接:https://wobfei.iteye.com/blog/707789
编程规范
蝈蝈俊.net
04-30
1896
编程规范1.基本要求1.1 程序结构清析,简单易懂,单个函数的程序行数不得超过100行。1.2 打算干什么,要简单,直接了当,代码精简,避免垃圾程序。1.3 尽量使用标准库函数和公共函数。1.4 不要随意定义全局变量,尽量使用局部变量。1.5 使用括号以避免二义性。2.可读性要求2.1 可读性第一,效率第二。2.2 保持注释与代码完全一致。2.3 每个源程序文件,都有文件头说明,说明规格见规范。2
32丨 理论五:让你最快速地改善代码质量的20条编程规范(中)1
08-03
本文将深入探讨那些能够让你迅速改善代码质量的编程规范,特别是涉及到类与函数的规模、代码行的长度、空行的使用、缩进方式和大括号的放置等问题。 ### 类与函数的适宜大小 首先,我们必须讨论关于类与函数的适宜...
33丨 理论五:让你最快速地改善代码质量的20条编程规范(下)1
08-03
【编程规范】是提高代码质量的关键,以下是20条实用的编程规范的下部分,旨在帮助开发者更快地提升代码可读性和可维护性。 1. **代码分割成更小的单元块**:遵循模块化和抽象的原则,将复杂的代码逻辑分解为更小的...
31丨理论五:让你最快速地改善代码质量的20条编程规范(上)1
08-04
在编程实践中,良好的命名和注释是提高代码质量的关键因素,它们直接关乎代码的可读性和可维护性。首先,我们来探讨命名方面的一些规范和建议。 1. **命名长度**:命名应该在准确传达含义的前提下尽可能简洁。长...
改善代码质量的6种重构模式
08-15
改善代码质量的6种重构模式 在软件开发中,代码质量是一个非常重要的方面。代码质量的好坏直接影响到软件的可维护性、可读性和可扩展性。在实际开发中,我们经常会遇到各种代码坏味道,如过大的类、过长的方法、...
改善代码质量编程规范 - 学习总结
指尖飞舞
02-06
669
命名与注释
命名
范围
项目名
包名
接口名
类名
函数名
变量名
参数名
原则建议
准确达意
对不同作用域,合理选择不同的长度。作用域较小如局部变量,可使用较短的缩写。
参考经典开源系统,使用耳熟能详的名字
借助上下文简化命名
借助类的信息简化属性和函数的命名,无需在属性和函数名字中再加入类名
借助函数的信息简化参数的命名
增加可读、可搜索醒
避免使...
代码质量要求
iteye_5055的博客
10-07
451
编码质量与规范要求
1 对于每一个变量、函数名及源代码文件名
1.1 必须给出有意义的英文名称,可以是缩写,如,userCnt, hitStat, pwdChk.
1.2 全局变量以g_开头,如,g_globalName.
1.3 变量首字母小写,如,userName.
1.4 对象的成员变量使用变量名加下划线方式表达,如, userName_.
1.5 函数的形参名必须以arg_为前...
设计模式学习笔记 - 规范与重构 - 6.快速改善代码质量的20条编程规范
最新发布
chenjian723122704的专栏
03-11
1101
命名的关键是能准确达意。对于不同作用域的命名,我们可以适当地选择不同的长度。可以借助类的信息来简化属性、函数的命名,利用函数的信息来简化函数参数的命名。命名要可读、可搜搜。不要使用生僻的、不好读的英文单词来命名。命名要符合项目的统一规范,也不要用些反直觉的命名。接口由两种命名方式:一种是在接口总带前缀 “I”;另一种是在接口的实现类中带后缀 “Impl”。对于抽象类,也有两种方式,一种是带上前缀 “Abstract”,一种是不带前缀。这两种都可以,关键是要在项目中统一。
代码质量规范
为谁伫立在风中
04-21
656
一般来说,在编写代码时,会使用一些优化技术,比如内存管理和数据结构,以提高软件的性能。静态代码分析工具可以在编码过程中检查代码,发现潜在的问题和不良实践,如未使用的变量、重复的代码、未处理的异常等等。满足代码质量规范的软件在使用过程中可以更好地保证质量,减少出现问题的可能性,有效地提高编写软件的效率,从而节省开发成本。代码质量规范的要求是可以帮助开发者更好地理清软件的架构、把握代码的可维护性、提高系统可靠性、减少错误、提高可读性。既能控制各层的复杂度,还可以以分层的思路去设计,也能提高代码的复用性。
华为编程规范与最佳实践:提升代码质量
华为软件编程规范和范例是为提升软件开发人员的代码质量,提供一套详细的编码指引和统一标准。这份文档不仅适用于华为公司的内部开发团队,也对所有软件开发者具有参考价值。规范旨在帮助开发者编写简洁、可维护、...
Ivanqhz
博客等级
码龄8年
101
原创
1553
点赞
1313
收藏
1136
粉丝
关注
私信
TA的精选
新
LLVM 中 Value 功能解析
974 阅读
新
CGSCC基本概念
817 阅读
热
unicode和utf-8互转
4803 阅读
热
4位全加器的实现
2661 阅读
热
可编程定时计数器8253/8254 - 8253控制字
2650 阅读
查看更多
2025年14篇
2024年87篇
大家在看
基于YOLO+AI的野生动物检测与识别系统
月考后别再围着成绩 “团团转”,家校可以都轻松
Java字符串操作实战指南
LibMesh介绍和使用
一顿火锅的网络协议课
上一篇:
染色算法的简单概述
下一篇:
定义类与类之间的交互关系
目录
展开全部
收起