侧边栏壁纸
博主头像
MingITBoy博主等级

卑微码农一枚,热爱编程

  • 累计撰写 9 篇文章
  • 累计创建 6 个标签
  • 累计收到 1 条评论
标签搜索

关于程序员最怕的命名

MingITBoy
2021-02-26 / 0 评论 / 0 点赞 / 931 阅读 / 6,061 字
温馨提示:
本文最后更新于 2021-02-26,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

naming-cheatsheet 是一个命名备忘录,记录命名的一些常见规范和约定。

简介

在编程工作中,命名是一件让很多开发者都头疼的事情。国外曾经有个一次关于程序员最难任务的投票调查,结果命名占了 49%。

img

一个好的变量或函数命名,应该能起到自解释的作用,甚至能减少我们代码的注释。

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, PascalCase,或者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)  

看看下表中如何应用此模式。

NamePrefixAction (A)High context (HC)Low context (LC)
getUser getUser
getUserMessages getUserMessages
handleClickOutside handleClickOutside
shouldDisplayMessageshouldDisplayMessage

上下文的顺序可能会影响变量的含义,例如shouldUpdateComponent意味着将要更新一个组件,换一下顺序变成shouldComponentUpdate,意味着组件将做自我更新。换句话说,高上下文(HC)强调了变量的含义。

动作

函数名称的动词部分,是描述函数作用的最终要的部分,如:

getXXX表示获取数据

function getFruitCount() {
  return this.fruits.length
}

setXXX表示设值

let fruits = 0

function setFruits(nextFruits) {
  fruits = nextFruits
}

setFruits(5)
console.log(fruits) // 5

resetXXX重置数据

const initialFruits = 5
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10

function resetFruits() {
  fruits = initialFruits
}

resetFruits()
console.log(fruits) // 5

fetchXXX请求数据

function fetchPosts(postCount) {
  return fetch('https://api.dev/posts', {...})
}

``removeXXX`移除数据,表示从某处删除某物

例如,如果您在搜索页面上有一组选定的过滤器,则从集合中删除其中一个过滤器是removeFilter,而不是deleteFilter

function removeFilter(filterName, filters) {
  return filters.filter((name) => name !== filterName)
}
const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)

deleteXXX删除数据,表示完全清楚某些事物

function deletePost(id) {
  return database.find({ id }).delete()
}

composeXXX从现有数据创建新数据

function composePageUrl(pageName, pageId) {
  return (pageName.toLowerCase() + '-' + pageId)
}

handleXXX处理某个动作(经常用来作为回调方法)

function handleLinkClick() {
  console.log('Clicked a link!')
}
link.addEventListener('click', handleLinkClick)

上下文

函数在其上运行的域。函数或方法通常是某些事物的动作,结合上下文,能够明确其操作的对象,或者要能反映出函数预期的数据类型。一些特定的情况下允许省略上下文,例如在JavaScript中,filterArray进行操作很常见,就没必要命名为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类型

const color = 'blue'
const isBlue = color === 'blue' // characteristic
const isPresent = true // state

if (isBlue && isPresent) {
  console.log('Blue is present!')
}

has描述是否具有某个状态或值,通常是boolean类型

/* Bad */
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0

/* Good */
const hasProducts = productsCount > 0

should反映肯定的条件,通常是boolean类型,加上特定的执行动作

function shouldUpdateUrl(url, expectedUrl) {
  return url !== expectedUrl
}

min/max表示最小值或最大值,描述边界或界限时使用

/**
 * Renders a random amount of posts within
 * the given min/max boundaries.
 */
function renderPosts(posts, minPosts, maxPosts) {
  return posts.slice(0, randomBetween(minPosts, maxPosts))
}

prev/next指示前一个或下一个状态,在描述状态转换时使用

function fetchPosts() {
  const prevPosts = this.state.posts

  const fetchedPosts = fetch('...')
  const nextPosts = concat(prevPosts, fetchedPosts)

  this.setState({ posts: nextPosts })
}

单复数

变量名称是单数还是复数,取决于值的单数还是复数。

/* Bad */  
const friends = 'Bob'  
const friend = ['Bob', 'Tony', 'Tanya']  

/* Good */  
const friend = 'Bob'  
const friends = ['Bob', 'Tony', 'Tanya']  
0

评论区