Guia de nomeclatura de variáveis e funções
Dar nome às coisas é uma tarefa difícil. Embora essas sugestões possam ser aplicadas a qualquer linguagem de programação, usarei JavaScript para ilustrá-las na prática.
Escreva em inglês
Nomeie suas variáveis e funções em inglês.
/* Ruim */
const primeiroNome = 'Gustavo'
const amigos = ['João', 'Raul']
/* Bom */
const firstName = 'Gustavo'
const friends = ['João', 'Raul']
Goste ou não, o Inglês é a língua dominante na programação: a sintaxe de todas as linguagens de programação é escrita em Inglês, assim como inúmeras documentações e materiais educacionais. Ao escrever seu código em Inglês, você aumenta drasticamente sua coesão.
Padrão de nomenclatura
Escolha um padrão de nomenclatura e siga o mesmo. Podendo ser camelCase
, PascalCase
, snake_case
, ou qualquer outro que te agrade ou agrade a equipe, contando que seja consistente. Algumas linguaguens de programação tem seu próprio contrato sobre padrão de nomenclaturas; para isso, olhe a documentação da linguaguem e verifique repositórios populares no Github!
/* Ruim */
const page_count = 5
const shouldUpdate = true
/* Bom */
const pageCount = 5
const shouldUpdate = true
/* Bom também */
const page_count = 5
const should_update = true
C-I-D
Um nome deve ser curto, intuitivo e descritivo:
-
Curto. Um nome não deve demorar para ser digitado e, portanto, para ser lembrado;
-
Intuitivo. Um nome deve ser lido de forma natural, o mais próximo do que se é usado comumente no idioma;
-
Descritivo. Um nome deve refletir o que faz/possui da maneira mais eficiente.
/* Ruim */
const a = 5 // "a" pode ser significar qualquer coisa
const isPaginatable = a > 10 // "Paginatable" não tem um som legal
const shouldPaginatize = a > 10 // Verbos compostos são muito divertidos!
/* Bom */
const postCount = 5
const hasPagination = postCount > 10
const shouldPaginate = postCount > 10 // alternativa
Evite contrações
Não use contrações. Elas não contribuem para nada além de diminuir a legibilidade do código. Encontrar um nome curto e descritivo pode ser difícil, mas a contração não é desculpa para não fazê-lo.
/* Ruim */
const onItmClk = () => {}
/* Bom */
const onItemClick = () => {}
Evite duplicar o contexto
Um nome não deve duplicar o contexto em que está definido. Sempre remova o contexto de um nome se isso não diminuir sua legibilidade.
class MenuItem {
/* O nome do método duplica o contexto (que é "MenuItem") */
handleMenuItemClick = (event) => { ... }
/* Lemos tranquilamente como `MenuItem.handleClick()` */
handleClick = (event) => { ... }
}
Reflita o resultado esperado
Um nome deve refletir o resultado esperado.
/* Ruim */
const isEnabled = itemCount > 3
return <Button disabled={!isEnabled} /> //estou verificando a negação da condição acima
/* Bom */
const isDisabled = itemCount <= 3
return <Button disabled={isDisabled} /> //estou verificando a condição acima
Nomeando funções
Padrão A/HC/LC
Existe um padrão muito útil pra se seguir quando precisar nomear funções:
prefixo? + ação (A) + alto (high) contexto (HC) + baixo (low) contexto? (LC)
Dê uma olhada em como este padrão pode ser aplicado na tabela abaixo.
Nome | Prefixo | Ação (A) | Alto contexto(HC) | Baixo contexto(LC) |
---|---|---|---|---|
getUser | get | User | ||
getUserMessages | get | User | Messages | |
handleClickOutside | handle | Click | Outside | |
shouldDisplayMessage | should | Display | Message |
Nota: A ordem do contexto afeta o significado de uma variável. Por exemplo,
shouldUpdateComponent
significa que você está prestes a atualizar um componente, enquantoshouldComponentUpdate
diz que o componente será atualizado por si só, e você apenas está contrlando quando isto deve acontecer.
Em outras palavras, alto contexto enfatiza o significado de uma variável.
Ações
A parte verbal do nome de sua função. A parte mais importante responsável por descrever o que a função faz.
get
Acessa o dado imediatamente (i.e. getter de dados internos abreviado).
function getFruitCount() {
return this.fruits.length
}
Veja também compose.
Você pode usar get
quando disparar operações assíncronas tais como:
async function getUser(id) {
const user = await fetch(`/api/user/${id}`)
return user
}
set
Seta uma variável de forma declarativa, com valor A
pro valor B
.
let fruits = 0
function setFruits(nextFruits) {
fruits = nextFruits
}
setFruits(5)
console.log(fruits) // 5
reset
Seta uma variável de volta ao seu valor ou estado iniciais.
const initialFruits = 5
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10
function resetFruits() {
fruits = initialFruits
}
resetFruits()
console.log(fruits) // 5
remove
Remove algo de algum lugar.
Por exemplo, se vc tem uma coleção de filtros selecionados em uma página de busca, remove um deles da coleção seria removeFilter
, não deleteFilter
(e isto é como naturalmente você diria em Inglês):
function removeFilter(filterName, filters) {
return filters.filter((name) => name !== filterName)
}
const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)
Veja também delete.
delete
Apaga completamente algo dos reinos da existência.
Imagine que você é um editor de conteúdo, e existe um post notório que você quer se livrar. Uma vez que você clicar no botão brilhante "Deletar post", o CMS dispara uma ação de deletePost
, não removePost
.
function deletePost(id) {
return database.find({ id }).delete()
}
Veja também remove.
remove
oudelete
?Quando a diferença entre
remove
edelete
não é tão óbvia pra você, Sugiro que olhe pra suas ações opostas -add
ecreate
.
A diferença chave entreadd
ecreate
é queadd
precisa de um destino enquantocreate
não precisa de um destino. Vocêadd
(adiciona) um item pra algum lugar, mas você não cria "create
em algum lugar".
Simplesmente pareieremove
comadd
edelete
comcreate
.Explicado em detalhes aqui.
compose
Cria novo dado a partir de um existente. Aplicado na maioria das vezes pra strings, objetos, ou funções.
function composePageUrl(pageName, pageId) {
return pageName.toLowerCase() + '-' + pageId
}
Veja também get.
handle
Lida com uma ação. Muitas vezes usado quando precisamos nomear um método de callback (retorno).
function handleLinkClick() {
console.log('Clicked a link!')
}
link.addEventListener('click', handleLinkClick)
Contexto
Um domínio no qual a função opera.
Uma função muitas das vezes é uma ação sobre algo. É importante declarar qual domínio operável é, ou ao menos um tipo de dado esperado.
/* Uma função pura operando com primitivos */
function filter(list, predicate) {
return list.filter(predicate)
}
/* Função operando exatamente com posts */
function getRecentPosts(posts) {
return filter(posts, (post) => post.date === Date.now())
}
Algumas suposições específicas de linguagens podem permitir omitir o contexto. Por exemplo, em JavaScript, é comum que um
filtro
opere em Arrays (vetores). Adicionar explicitamentefilterArray
seria desnecessário.
Prefixos
Prefixar realça o significado de uma variável. É raramente usado em nomes de função.
is
Descreve uma característica ou estado do contexto atual (usualmente boolean
).
const color = 'blue'
const isBlue = color === 'blue' // característica
const isPresent = true // estado
if (isBlue && isPresent) {
console.log('Blue is present!')
}
has
Descreve se o contexto atual possui um certo valor ou estado (usualmente boolean
).
/* Ruim */
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0
/* Bom */
const hasProducts = productsCount > 0
should
Reflete uma declaração condicional positiva (usualmente boolean
) casada com uma certa ação.
function shouldUpdateUrl(url, expectedUrl) {
return url !== expectedUrl
}
min
/max
Representa o valor mínimo ou máximo. Usado ao descrever limites.
/**
* Renderiza um valor aleatório de posts dentro de
* um dado limite mínimo/máximo.
*/
function renderPosts(posts, minPosts, maxPosts) {
return posts.slice(0, randomBetween(minPosts, maxPosts))
}
prev
/next
Indica o estado prévio ou posterior de uma variável no contexto atual. Usado ao descrever transição de estado.
async function getPosts() {
const prevPosts = this.state.posts
const latestPosts = await fetch('...')
const nextPosts = concat(prevPosts, latestPosts)
this.setState({ posts: nextPosts })
}
Singular e Plural
Tal qual um prefixo, nomes de variávels podem estar no singular ou no plural dependendo se elas contém um valor único ou múltiplos valores.
/* Ruim */
const friends = 'Bob'
const friend = ['Bob', 'Tony', 'Tanya']
/* Bom */
const friend = 'Bob'
const friends = ['Bob', 'Tony', 'Tanya']