编程命名规范(网文)
一个好的变量或函数命名,应该能起到自解释的作用,甚至能减少我们代码的注释。
naming-cheatsheet是一个命名备忘录,记录一些常见的规范约定,并提供简单的例子说明。如果能够严格遵守这些规范,相信我们的代码可读性会大大提升,下面就来介绍 naming-cheatsheet 提供的一些建议。
项目地址:
https://github.com/kettanaito/naming-cheatsheet
使用英语
这是最基本的一条规则了,英语是编程中的主要语言,所有编程语言的语法都是用英语编写的,通过英语编写代码,可以大大提高其通用性。对于我们国内开发者来说,一定要避免拼音甚至是直接的中文命名。
/* Bad */ const primerNombre = 'Gustavo' const amigos = ['Kate', 'John'] /* Good */ const firstName = 'Gustavo' const friends = ['Kate', 'John']
命名风格
选择一种命名的风格,并且严格遵守,可以是camelCase,或者snake_case,或者是其他任何的风格,最重要的是要保持一致,不管是个人开发者还是团队,保持一致的命名风格很重要,不要混合使用。
/* Bad */ const page_count = 5 const shouldUpdate = true /* Good */ const pageCount = 5 const shouldUpdate = true /* Good as well */ const page_count = 5 const should_update = true
遵守SID原则
命名应该简短、直观并且具有描述性,遵循SID原则。
- Short。简短,避免输入太长,但是也应该注意不能简写到失去其原本的意义。
- Intuitive。直观,并且尽可能接近自然语言。
- Descriptive。以最有效的方式反映其作用或目的。
/* Bad */ const a = 5 // "a" could mean anything const isPaginatable = a > 10 // "Paginatable" sounds extremely unnatural const shouldPaginatize = a > 10 // Made up verbs are so much fun! /* Good */ const postCount = 5 const hasPagination = postCount > 10 const shouldPaginate = postCount > 10 // alternatively
避免过度的简写
命名要简短,但是要避免钻牛角尖,命名最重要的是要让人能看懂,过度的缩写如果失去了其原本的意义,降低了代码的可读性,那就不应该这么做,宁愿多写几个字母。
/* Bad */ const onItmClk = () => {} /* Good */ const onItemClick = () => {}
避免上下文重复
有时候在一段代码中可能会出现类似意义的变量定义,这个时候要避免命名的重复。
class MenuItem { /* Method name duplicates the context (which is "MenuItem") */ handleMenuItemClick = (event) => { ... } /* Reads nicely as `MenuItem.handleClick()` */ handleClick = (event) => { ... } }
反映预期结果
变量或函数的命名应该能反映预期的结果。
/* Bad */ const isEnabled = itemCount > 3 return <Button disabled={!isEnabled} /> /* Good */ const isDisabled = itemCount <= 3 return <Button disabled={isDisabled} />
命名的模式
可以参考以下类似的模式来做命名。
A/HC/LC模式
可以遵循A/HC/LC,即
prefix? + action (A) + high context (HC) + low context? (LC)
name | prefix | A | HC | LC |
---|---|---|---|---|
getUser | get | User | ||
getUserMessages | get | User | Messages | |
handleClickOutside | handle | Click | Outside | |
shouldDisplayMessage | should | Display | Message |
上下文的顺序可能会影响变量的含义,例如shouldUpdateComponent意味着将要更新一个组件,换一下顺序变成shouldComponentUpdate,意味着组件将做自我更新。
动作
函数名称的动词部分,是描述函数作用的最终要的部分,如:
- getXXX,表示获取数据
- setXXX,表示设值
- resetXXX,重置数据
- fetchXXX,请求数据
- removeXXX,移除数据,表示从某处删除某物
- deleteXXX,删除数据,表示完全清楚某些事物
- composeXXX,从现有数据创建新数据
- handleXXX,处理某个动作
上下文
函数或方法通常是某些事物的动作,结合上下文,能够明确其操作的对象,或者要能反映出函数预期的数据类型。一些特定的情况下允许省略上下文,例如在JavaScript中,filter对Array进行操作很常见,就没必要命名为filterArray了。
/* A pure function operating with primitives */ function filter(predicate, list) { return list.filter(predicate) } /* Function operating exactly on posts */ function getRecentPosts(posts) { return filter(posts, (post) => post.date === Date.now()) }
前缀
前缀用来增强变量的含义,如:
- is,描述特征或状态,通常是boolean类型
- has,描述是否具有某个状态或值,通常是boolean类型
- should,反映肯定的条件,加上特定的执行动作
- min/max,描述边界或界限时使用
- prev/next,指示前一个或下一个状态
单复数
变量名称是单数还是复数,取决于值的单数还是复数。
/* Bad */ const friends = 'Bob' const friend = ['Bob', 'Tony', 'Tanya'] /* Good */ const friend = 'Bob' const friends = ['Bob', 'Tony', 'Tanya']
函数入参不要太多
❌错误案例:重量/体积 同类型参数顺序错误导致问题// 错误的方法定义,参数过多且容易混淆 public void calculateShippingCost(double weight, double volume, double length, double width, double height, String destination) { // 假设这里有计算运费的逻辑 } // 这里将重量和体积的顺序弄反了 service.calculateShippingCost(30.0, 50.0, 10.0, 5.0, 3.0, "New York"); // 实际上应该是: service.calculateShippingCost(50.0, 30.0, 10.0, 5.0, 3.0, "New York"); ✅正确案例:在这个示例中,由于重量和体积的顺序弄反,计算出来的运费会有误。为了避免这种错误,可以将这些参数封装成一个类:public class ShippingDetails { private double weight; private double volume; private double length; private double width; private double height; private String destination; // 构造方法、getter和setter省略 } // 使用参数对象来简化方法签名 public void calculateShippingCost(ShippingDetails details) { // 假设这里有计算运费的逻辑 }
谨慎使用可变参数
public void info(String msg); public void info(String format, Object arg); public void info(String format, Object arg1, Object arg2); public void info(String format, Object... arguments); public void info(String msg, Throwable t);
重载方法,必须要使用的时候在使用可变参数。因为函数内部每次需要一个数组来存放可变参数。
条件语句
三个及以下使用if/else,以上使用switch。