美文网首页
设计模式 - 编程规范

设计模式 - 编程规范

作者: Zeppelin421 | 来源:发表于2022-04-19 08:55 被阅读0次

编程规范大部分都简单明了,在代码细节方面,能立竿见影地改善代码质量。持续低层次、小规模重构依赖的基本上都是编码规范,这也是改善代码可读性的有效手段。

命名

命名对于代码的可读性来说非常重要,甚至可以说起决定性作用的。对于影响范围比较大的命名,比如包名、接口、类名,一定要反复斟酌、推敲。

  • 命名多长最合适
    在足够表达其含义的情况下,命名是越短越好。
    对于一些默认的、大家都比较熟知的词(sec、str、num、doc)推荐用缩写。
    对于作用域比较小的变量可以使用相对短的命名,例如函数内的临时变量;
    对于类名这种作用域比较大的,推荐用更长的命名方式
    命名的一个原则就是以能准确达意为目标。对于编码者自己来说,总感觉用什么样的命名都可以达意,但对不熟悉代码的同事来说就不这么认为了。所以命名的时候一定要学会换位思考,假设自己不熟悉这块代码,从代码阅读者的角度去考量命名是否足够直观。

  • 利用上下文简化命名

public class User {
    private String userName;
    private String userPassword;
    private String userAvatarUrl;
    //...
}

public void uploadUserAvatarImageToAliyun(String userAvatarImageUri);
//利用上下文简化为:
public void uploadUserAvatarImageToAliyun(String imageUri);
  • 命名要可读、可搜索
    “可读”指不要用一些特别生僻、难发音的英文单词来命名,例如:plateaux、eyrie。可以用一些易读的词,例如:inkstone。
    “可搜索”指用IDE编写代码时经常会用到“关键词联想”的方法来自动补全和搜索。因此在命名是最好能符合整个项目的命名习惯。比如:大家都用selectXXX,那就避免个人使用queryXXX;大家都用insertXXX,个人就不要使用addXXX

  • 如何命名接口和抽象类
    接口命名通常两种比较常见:一种加前缀“i”,比如 UserService implements IUserService,另一种不加前缀,比如 UserServiceImpl implements UserServiceImpl
    抽象类通常也有两种,一种加前缀“Abstract”,另一种不加
    对于接口和抽象类,选择那种命名方式都是可以的,只要项目里保持一致就行

注释

注释跟命名一样也很重要。很多人认为好的命名完全可以替代注释,如果需要注释,那说明命名不够好,这种观点有点太过极端。命名再好,毕竟有长度限制,不可能足够详尽,这时候注释就是一个很好的补充。

  • 注释该写什么
    注释的目的就是让代码更容易看懂。只要符合这个要求的内容,就可以写到注释里。注释的内容包括:做什么、为什么、怎么做。
/**
 * (what) Bean factory to create beans. 
 * (why) The class likes Spring IOC framework, but is more lightweight. 
 * (how) Create objects from different sources sequentially:
 * user specified object > SPI > configuration > default object.
 */
public class BeansFactory {
    // ...
}

很多人认为“做什么、怎么做”可以在代码中体现出来,所以不要写,其实不然:

  • 注释比代码承载的信息更多
    对于类来说,包含的信息比较多,一个简单的命名不够全面详尽,这个时候在注释中写明“做什么”就合情合理
  • 注释起到总结性作用、文档的作用
    在注释中,关于具体的代码实现思路,我们可以写一些总结性的说明、特殊情况的说明。这样能够让阅读代码的人通过注释就能大概了解代码的实现思路,阅读起来就会更加容易
  • 一些总结性注释能让代码结构更清晰
    对于逻辑比较复杂的代码或者比较长的函数,如果不好提炼、不好拆分成小的函数调用,可以借助总结性的注释来让代码结构更清晰、更有条理
  • 注释是不是越多越好
    注释本身有一定的维护成本,所以并非越多越好。类和函数一定要写注释,而且要写得尽可能全面、详细,而函数内部的注释要相对少一些,一般都是靠好的命名、提炼函数、解释性变量、总结性注释来提高代码的可读性

代码风格

在一个团队、项目中保持风格统一,让代码像同一个人写出来的,整齐划一,这才是最好的风格。这样能减少阅读干扰,提高代码的可读性。

  • 类、函数多大才合适
    函数代码行数不好超过一个显示屏的垂直高度(大约50行左右),因为超过一屏之后,在阅读代码的时候,为了串联前后的代码逻辑,可能需要频繁的上下滚动屏幕,阅读体验不好,还容易出错。
    对于类的代码行数的限制有个间接的判断标准:当一个类的代码读起来让你感觉头大;实现某个功能时不知道该用那个函数了;想用哪个函数翻半天找不到;只用一个小功能要引入整个类;此时就说明类的行数太多了。

  • 一行代码多长最合适
    Google Java Style Guide中,一行代码最长限制100字符。
    遵循一个原则:一行代码最长不能超过IDE显示的宽度。需要滚动鼠标才能查看一行的全部代码,显然不利于代码的阅读。

  • 善用空行分隔单元块
    对于比较长的函数,为了让逻辑更加清晰,可以使用空行来分隔各个代码块。在类内部,成员变量与函数之间、静态成员变量与普通成员变量之间、函数之间,甚至成员变量之间,都可以通过添加空行的方式,让不同模块的代码之间的界限更加明确

  • 四格缩进还是两格缩进
    不管是用两格缩进还是四格缩进,一定不要用tab键缩进。整个团队保持一致即可。推荐两格缩进,节省空间

  • 类中成员的排列顺序
    类中先写成员变量后写函数。成员变量之间或函数之间,先写静态成员变量或函数,后写普通变量或函数

编程技巧

  • 把代码分割成更小的单元块
    大部分人阅读代码的习惯是先看整体再看细节。所以要有模块化和抽象思维,善于将大块的复杂逻辑提炼成类或函数,屏蔽掉细节,这样能极大地提高代码的可读性。

  • 避免函数参数过多
    函数包含的参数 >=5 时会影响到代码的可读性,使用起来也不方便。参数过多处理方法:考虑函数是否职责单一,能否通过拆分成多个函数的方式减少参数;将函数的参数封装成对象,如果函数是对外暴露的远程接口,将参数封装成对象还可以提高接口的兼容性。

  • 勿用函数参数来控制逻辑
    不要在函数中用布尔类型的标识参数来控制内部逻辑,true走A逻辑,false走B逻辑。这明显违背了单一职责原则和接口隔离原则。如果函数是private或者拆分后的两个函数经常同时被调用,可以酌情考虑保留标识参数。
    根据参数是否为null来控制逻辑的也应该将其拆分成多个函数。

  • 函数设计要职责单一
    函数的设计也需要满足单一职责原则,函数的粒度比较小,代码行数少,所以在应用单一职责时能多单一就多单一

  • 移除过深的嵌套层次
    代码嵌套最好不超过两层,过深的嵌套本身理解就比较费劲,而且嵌套过深很容易因为代码多次缩进导致语句超过一行的长度,影响代码的整洁和阅读

    • 去掉多余的 if else语句
    • 使用 continue、break、return提前退出嵌套
    • 调整执行顺序来减少嵌套
    • 将部分嵌套逻辑封装成函数调用,减少嵌套
public List matchStrings(List strList,String substr) {
    List matchedStrings = new ArrayList<>();
    if (strList != null && substr != null) {
        for (String str : strList) {
            // 跟下面的if语句可以合并在一起 
            if (str != null) { 
                if (str.contains(substr)) { 
                    matchedStrings.add(str); 
                } 
            } 
        } 
    } 
    return matchedStrings;
}
  • 学会使用解释性变量
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)) { 
    // ...
}
// 引入解释性变量后逻辑更加清晰
boolean isSummer = date.after(SUMMER_START)&&date.before(SUMMER_END);
if (isSummer) { 
    // ...
}

相关文章

  • 设计模式 - 编程规范

    编程规范大部分都简单明了,在代码细节方面,能立竿见影地改善代码质量。持续低层次、小规模重构依赖的基本上都是编码规范...

  • 面向对象、设计原则、设计模式、编程规范、重构

    面向对象、设计原则、设计模式、编程规范、重构 面向对象 主流的三个编程风格有:面向对象,面向过程,函数式编程。 面...

  • 2018-03-12

    编程规范推荐 1.命名风格推荐 1.1 如果使用到了设计模式,建议在类名中体现出具体模式。 说明: 将设计模式...

  • 设计模式之美读书笔记

    面向对象、设计原则、设计模式、编程规范、重构,五者的关系 面向对象,由于它具有丰富的特性,例如继承、多态、封装、抽...

  • 面向指针编程(一)

    面向对象编程,面向设计模式编程(亦即设计模式),面向接口编程,面向模板编程(亦即泛型编程),面向函数编程(亦即函数...

  • 前端学习的基本总结

    目录 1.为什要遵守代码规范 2.css代码规范 3.js代码规范与设计模式3.1 js代码规范3.2 设计模式 ...

  • 责任链模式

    Objective-C编程之道 iOS设计模式解析iOS设计模式解析-工厂模式iOS设计模式解析-抽象工厂模式iO...

  • 外观模式

    Objective-C编程之道 iOS设计模式解析iOS设计模式解析-工厂模式iOS设计模式解析-抽象工厂模式iO...

  • 工厂模式

    Objective-C编程之道 iOS设计模式解析iOS设计模式解析-工厂模式iOS设计模式解析-抽象工厂模式iO...

  • 抽象工厂模式

    Objective-C编程之道 iOS设计模式解析iOS设计模式解析-工厂模式iOS设计模式解析-抽象工厂模式iO...

网友评论

      本文标题:设计模式 - 编程规范

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