编码用这16个命名规则能让你少写一半以上的注释!

更新日期: 2022-07-29阅读: 42标签: 命名作者: 岛上码农

前言

本篇介绍如何设计合理的名称,包括变量名称,函数名称等等。代码胜过好注释,通过设计合理的命名能够让代码更易懂。

规则1:保持命名形式的一致性

对于代码中同样的事物使用相同的名称,同时应该遵循用户的习惯用语。很多人写变量名称可能会忘记之前的命名方式,从而又来一个新的名称。比如 Image 对象,可能在 A 文件称之为 image,在 B 文件又称之为 picture,这样的话会让人很困惑。最佳的方式是:

  • 对于产品层面的实体对象:建议是前后端、数据表都统一实体对象名称;
  • 对于各自语言的一些特定的对象或组件,建议开发团队统一实体对象命名规则。
  • 不要创造新名词!也许你看得懂,但不代表别人看得懂。
  • 不要使用拼音,更不要使用拼音缩写!中文翻译成英文的时候,挑简单易懂的词汇。

下面是一些命名的对比:

// 正确示例
pageCount         // 表示页数的字段
updatePageCount() // 与 pageCount 名称保持一致
toSomething()     // 与 Iterable 的 toList() 的写法一致
asSomething()     // 与 List 的 toMap() 写法一致
Point             // 用户习惯用语
  
// 错误示例
renumberPages()   // 与 pageCount 名称没有一致
convertToSomething()  // 与通常的 toX()不一致
wrappedAsSomething()  // 与通常的 asX() 不一致
Cartesian                           // 不是用户的习惯用语

使用大家熟知的用语,能够快速让用户了解所涉及到的只是领域,从而避免了新名词或不熟悉的词汇增加理解代码的难度。

规则2:避免缩写

除非缩写是众所周知的的词汇,否则不要缩写。即便是使用缩写,也应该遵循习惯的大小写规则。

// 正确示例
pageCount
buildRectangles
IOStream
HttpRequest
  
// 错误示例
numPages    // num 缩写不合适
buildRects  // Rects 缩写很难和 Rectangles 对应
InputOutputStream  // 没有使用简单易懂的缩写
HypertextTransferProtocolRequest // 没有使用简单易懂的缩写

规则3:将描述事物最准确的名词放在最后

当有多个名词组合来描述一个对象时,将最贴近事物对应的名词放在最后面,这样在语义上更好理解变量对应的是一个什么样的事物。

// 正确示例
pageCount             // 页码的数量(count)
ConversionSink        // 用于转换的 sink
ChunkedConversionSink //  一个chunked 的 Conversation Sink
cssFontFaceRule       // CSS 中字体规则(rule)
  
// 错误示例
numPages                               // 并不是 pages 的集合
CanvasRenderingContext2D // 并不是 2D 对象
RuleFontFaceCss                  // 并不是 CSS

规则4:让代码像语句一样连贯

让代码像语句一样连贯时,读起来的时候就能够知道代码的具体意思了 —— 此时就无需写注释了!,比如下面的例子,一看代码就知道是在做什么事情。

// 正确示例
if (errors.isEmpty) ...

subscription.cancel();

monsters.where((monster) => monster.hasClaws);

而下面这种就有点不太好理解了。

// 是清空 error 还是盘点 errors 是不是空?
if (errors.empty) ...

// 反转什么?反转后是什么状态?
subscription.toggle();

// 是过滤包含的还是不包含满足条件的?
monsters.filter((monster) => monster.hasClaws);

但是并不是为了编造语句而强行造一个句子,使用简单易懂的短语,让阅读者能够清晰、快速了解代码的意思就可。比如下面的例子就有点过度了。

// 错误示例
if (theCollectionOfErrors.isEmpty) ...

monsters.producesANewSequenceWhereEach((monster) => monster.hasClaws);

规则5:对于非布尔类型的属性或变量使用名词

因为是一个属性,如果不是布尔类型的话,肯定会是某个对象,因此使用名词能够更清晰地表名属性或变量对应的事物。同时,如果涉及操作后的事物,应该用形容词或动词的完成时(表示已完成)来修饰,而不是直接用动词+名词,这样会误以为是操作一个对象的动作。

// 正确示例
list.length
context.lineWidth
quest.rampagingSwampBeast
sortedList
  
// 错误示例
list.deleteItems
sortList

规则6:对于代表可执行某类操作布尔属性,优先使用能动词

我们经常会用布尔值标识一个对象能进行什么操作,比如是否能够更新,是否能够关闭。推荐使用能动词,这样的语义更加清晰。而动词转换后的形容词其实语义并不清晰,而且有些词汇并不那么直观。

// 正确示例
if (widget.canUpdate) ...
if (window.canClose) ...
if (container.hasElements) ...
if (request.shouldResume) ...

// 错误示例
if (widget.updatable) ...
if (window.closeable) ...
if (container.withElements) ...
if (request.resumable) ...

规则7:对于布尔类型的参数,不要使用动词

对于布尔型函数参数,不使用动词,而是形容词会更易读。

// 正确示例
Isolate.spawn(entryPoint, message, paused: false);
var copy = List.from(elements, growable: true);
var regExp = RegExp(pattern, caseSensitive: false);

规则8:对于布尔型属性和变量,应该使用正向名称

这个说起来有点抽象,实际看一个例子就知道了。当你用反向属性名称的时候,赋布尔值的时候理解起来会很r绕。比如 isNotEmpty = true,你得思考1-2秒才能够明白什么意思。而实际上,使用反向布尔值的,在写条件表达式的时候,一旦脑子短路,很容易导致 bug 出现。

// 正确示例
bool isEmpty;

// 错误示例
bool isNotEmpty;

当然,对于某些场合,可能应用会经常直接使用反向值做判断,那时候如果用正向名称可能适得其反,因为你还需要对其进行一次取反。而相比随处可见的取反操作符 !,直接使用负向命名会更好。比如我们要拦截未成年人才能够使用某项功能。

// 错误示例
bool isAdult;
if (! isAdult) {
  return 'Not Allowed for Non Adults'.
}

// 正确示例
bool isNotAdult;
if (isNotAdult) {
  return 'Not Allowed for Non Adults'.
}

规则10:使用祈使动词来命名函数或那些产生其他效果的方法

使用祈使动词描述函数时,我们能够清晰地知道这个函数的功能是要做一件事情,有点像是一个命令。对于明确操作对象的,可以加上操作对象的名称或描述词。

// 正确示例
list.add('element');
queue.removeFirst();
controller.forward();
refreshController.loadMore();

规则11:对于主要目的是返回一个值的函数优先使用名词或非祈使动词

这类函数通常做得事情不多,主要目的是返回一个值。如果没有参数的话,通常会是一个 getter 操作。但有有时候会需要传递一个参数,例如数组下标,数据过滤条件等。这个时候使用名词或副词的话会更有益于理解代码,而如果加上动词会感觉有点多余(通常会加 get,find 之类的动词)。

// 正确示例
var element = list.elementAt(3);
var first = list.firstWhere(test);
var char = string.codeUnitAt(4);

规则12:不要在方法名称开头加 get

大部分情况下,应当移除 get。例如,与其使用 getBreakfastOrder,还不如定一个一个 getter 属性,名称为 breakfastOrder。如果确实需要方法获取一个对象,那么也应该避免使用 get,可以参考下面两条建议:

  • 如果调用者更关系返回值,那么可以直接去掉 get,使用名词作为方法名词,例如breakfastOrder(),或者使用规则11。
  • 如果调用这关心这个方法做什么事情,那么可以用更精确的描述动词,例如 create、download、fetch、calculate、request 等等。

规则13:如果方法是将一个对象复制成为另一种表现形式,那么使用 toX() 形式

这和下面的规则14可能觉得有点不好区分,其实这个意思就是这样的操作是将对象的转为新的一种形式表述的对象。比如我们常见的 toJson,toString,toSet,toLocal 形式。这种方式大部分是不可逆的。

规则14:如果返回的是原对象的不同的表现形式,那么使用 asX() 形式

asX 其实就像我们做对象的转换一样,我们有下面的代码:

if ((object as String) == 'a') {
  ...
}

asX 形式也是类似的,转换后的对象其实还能够反映原对象的特性,也就是可以通过一定的手段再转换回来。例如下面的情况:

var map = table.asMap();
var list = bytes.asFloat32List();
var future = subscription.asFuture();

规则15:不要在方法名称上重复参数名

参数名可以和方法的动词连起来读,添加参数名有点多余。

// 正确示例
list.add(element);
map.remove(key);

// 错误示例
list.addElement(element)
map.removeKey(key)

这个不是绝对的,比如如果加上参数能够消除同一个类不同函数的含义的话,那么是可以的,例如下面的例子。

// 正确示例
map.containsKey(key);
map.containsValue(value);

规则16:对于泛型,遵循通用的助记符

通常在泛型中,我们会用如下的助记符来表示不同的泛型参数,需要遵循这样的规则来帮助理解泛型。

  • E:表示集合类的泛型参数,例如:
class IterableBase<E> {}
class List<E> {}
class HashSet<E> {}
class RedBlackTree<E> {}
  • K和 V表示 key 和 value 泛型参数,例如:
class Map<K, V> {}
class Multimap<K, V> {}
class MapEntry<K, V> {}
  • R 表示返回值泛型参数,例如:
abstract class ExpressionVisitor<R> {
  R visitBinary(BinaryExpression node);
  R visitLiteral(LiteralExpression node);
  R visitUnary(UnaryExpression node);
}
  • 其他情况,通常使用 T、S 和 U 来标识泛型,实际中如果能够有助于理解,也可以使用单词(首字母大写)作为泛型参数,下面的3个例子都是没问题的。
class Future<T> {
  Future<S> then<S>(FutureOr<S> onValue(T value)) => ...
}

class Graph<N, E> {
  final List<N> nodes = [];
  final List<E> edges = [];
}

class Graph<Node, Edge> {
  final List<Node> nodes = [];
  final List<Edge> edges = [];
}

总结

我们经常为写注释而烦恼,觉得写注释有点浪费时间。实际上,如果用好了代码命名,可以节省很多写注释的时间。而真正要写的其实更多地是文档,通过文档能够帮助我们、帮助团队梳理开发业务流程、逻辑。因此,编码的更高境界是用好的编码命名规则及风格来通过代码理解功能,做到少写注释,然后腾出时间来写文档。

链接: https://www.fly63.com/article/detial/11963

这些 CSS 命名规范将省下你大把调试时间

CSS 算不上是最优美的『语言』,但迄今二十多年来,它都是美化 web 举足轻重的工具。尽管如此,CSS 写得越多,你越容易发现一个巨大的弊端。因为维护 CSS 真是老大难。

web前端开发_文件/目录/样式/函数等命名规范

在web前端开发中遇到不知道给元素或变量起什么名字的问题,中文拼音太俗气,随便敲几个字母又影响代码的查读性。于是总结这些命名规范。

CSS命名规范_常用的CSS命名规则

CSS命名规范(规则)常用的CSS命名规则 ,注意事项:1.一律小写; 2.尽量用英文; 3.不加中横和下划线;  4.尽量不缩写,除非一看就明白的单词。 

JS的解析与执行过程—全局预处理阶段之命名冲突的处理策略

不论var f 与function f 的先后顺序如何,该代码执行的结果总是弹出function f 的字符串,为什么呢?像这种函数与变量命名冲突时JS的处理原则又是什么?

如何看待CSS中BEM的命名方式?

BEM的意识就是块(block)、元素(element)、修饰符(modifier),是由yandex团队提出的一种CSS Class命名方法。但至少他可以使我们命名的时候达到一定的统一,我们可以学习其优秀的方面将其纳为己用。

BEM的命名规范

CSS 的命名规范又叫做BEM规范,为的是结束混乱的命名方式,达到一个语义化的CSS命名方式。 BEM是三个单词的缩写:Block(块)代表更高级别的抽象或组件,Element(元素) Block的后代,以及Modifier(修饰) 不同状态的修饰符

常用的CSS命名规则

应该很多人都会有PO这种东西,但是对刚学CSS的人真的很重要,尤其像我这种英文不好的人,这些是必背的的单字喔^^,这些数据只是我在学习的时候,参考别人的数据之后用自己的思考整理出来的,像参考书写的真的都看不懂

是否需要重新命名 JavaScript?

最近,LinkedIn 的 JavaScript 组提出了一个有趣的问题:是否需要重新命名 JavaScript?众所周知,JavaScript 与 Java 无关。数十年来,这使非技术经理和招聘人员感到困惑。

前端BEM命名方式的思考

思考来源于要给切图网 qietu.com 改一次版,作为前端开发服务商,我觉得应该要有自己的一款前端CSS框架,并且这个框架不应该只是随便写写,最好能够用在官网上,拿官网做背书,于是在研究了火狐

大驼峰命名规则是什么?

大驼峰命名规则又称骆驼式命名法(Camel-Case),是电脑程式编写时的一套命名规则(惯例)。是指混合使用大小写字母来构成变量和函数的名字。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!