naming-cheatsheet/README.md

352 lines
8.5 KiB
Markdown
Raw Normal View History

2017-08-25 16:10:23 +02:00
<p align="center">
2018-01-12 09:59:02 +01:00
<a href="https://github.com/kettanaito/naming-cheatsheet">
<img src="./naming-cheatsheet.png" alt="Naming cheatsheet" />
</a>
2017-08-25 16:10:23 +02:00
</p>
2017-06-30 10:24:03 +02:00
# Naming cheatsheet
2021-01-16 15:58:59 +01:00
2021-01-16 17:24:31 +01:00
- [Naming convention](#naming-convention)
- [S-I-D](#s-i-d)
- [Avoid contractions](#avoid-contractions)
- [Avoid context duplication](#avoid-context-duplication)
- [Reflect expected result](#reflect-expected-result)
- Naming functions
- [A/HC/LC pattern](#ahclc-pattern)
- [Actions](#actions)
- [Context](#context)
- [Prefixes](#prefixes)
- [Singular and Plurals](#singular-and-plurals)
---
2018-09-13 10:28:54 +02:00
Naming things is hard. This sheet attempts to make it easier.
Although these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.
## Naming convention
2021-01-16 15:58:59 +01:00
2021-01-17 04:44:38 +01:00
Pick **one** naming convention and follow it. It may be `camelCase`, or `snake_case`, or anyhow else, it does not matter. What matters is for it to remain consistent.
2018-01-12 09:59:02 +01:00
2017-06-30 12:37:41 +02:00
```js
/* Bad */
2018-09-13 10:28:54 +02:00
const pages_count = 5
const shouldUpdate = true
2017-06-30 12:37:41 +02:00
/* Good */
2018-09-13 10:28:54 +02:00
const pagesCount = 5
const shouldUpdate = true
2017-06-30 12:37:41 +02:00
/* Good as well */
2018-09-13 10:28:54 +02:00
const pages_count = 5
const should_update = true
2017-06-30 12:37:41 +02:00
```
2018-01-12 09:59:02 +01:00
2018-09-13 10:28:54 +02:00
## S-I-D
2021-01-16 15:58:59 +01:00
A name must be _short_, _intuitive_ and _descriptive_:
- **Short**. A name must not take long to type and, therefore, remember;
- **Intuitive**. A name must read naturally, as close to the common speech as possible;
- **Descriptive**. A name must reflect what it does/possesses in the most efficient way.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
2017-06-30 10:49:04 +02:00
/* Bad */
2018-09-13 10:28:54 +02:00
const a = 5 // "a" could mean anything
2021-01-16 15:58:59 +01:00
const isPaginatable = postsCount > 10 // "Paginatable" sounds extremely unnatural
const shouldPaginatize = postsCount > 10 // Made up verbs are so much fun!
2017-06-30 10:24:03 +02:00
2017-06-30 10:49:04 +02:00
/* Good */
2018-09-13 10:28:54 +02:00
const postsCount = 5
2021-01-16 15:58:59 +01:00
const hasPagination = postsCount > 10
const shouldDisplayPagination = postsCount > 10 // alternatively
2017-06-30 10:24:03 +02:00
```
2017-06-30 12:37:41 +02:00
2018-09-13 10:28:54 +02:00
## Avoid contractions
2018-12-10 10:14:57 +01:00
Do **not** use contractions. They contribute to nothing but decreased readability of the code. Finding a short, descriptive name may be hard, but contraction is not an excuse for not doing so.
2018-04-14 10:10:09 +02:00
```js
/* Bad */
2018-09-13 10:28:54 +02:00
const onItmClk = () => {}
2018-04-14 10:10:09 +02:00
/* Good */
2018-09-13 10:28:54 +02:00
const onItemClick = () => {}
2018-04-14 10:10:09 +02:00
```
2018-09-13 10:28:54 +02:00
## Avoid context duplication
A name should not duplicate the context in which it is defined. Always remove the context from a name if that doesn't decrease its readability.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
class MenuItem {
2018-09-13 10:28:54 +02:00
/* Method name duplicates the context (which is "MenuItem") */
2017-06-30 10:24:03 +02:00
handleMenuItemClick = (event) => { ... }
2021-01-16 15:58:59 +01:00
2018-09-13 10:28:54 +02:00
/* Reads nicely as `MenuItem.handleClick()` */
2017-06-30 10:24:03 +02:00
handleClick = (event) => { ... }
}
```
2018-01-12 09:59:02 +01:00
2018-09-13 10:28:54 +02:00
## Reflect expected result
A name should reflect the expected result.
```jsx
2017-06-30 10:49:04 +02:00
/* Bad */
2021-01-16 15:58:59 +01:00
const isEnabled = itemsCount > 3
2018-09-13 10:28:54 +02:00
return <Button disabled={!isEnabled} />
2017-06-30 10:49:04 +02:00
/* Good */
2021-01-16 15:58:59 +01:00
const isDisabled = itemsCount <= 3
2018-09-23 11:07:03 +02:00
return <Button disabled={isDisabled} />
2017-06-30 10:49:04 +02:00
```
2017-06-30 10:24:03 +02:00
2018-05-10 10:19:49 +02:00
---
2018-09-13 10:28:54 +02:00
# Naming functions
## A/HC/LC Pattern
2018-12-10 10:14:57 +01:00
2018-09-13 10:28:54 +02:00
There is a useful pattern to follow when naming functions:
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```
2017-12-20 11:31:12 +01:00
prefix? + action (A) + high context (HC) + low context? (LC)
2017-06-30 10:24:03 +02:00
```
2017-06-30 12:29:56 +02:00
2018-12-10 10:14:57 +01:00
Take a look at how this pattern may be applied in the table below.
2017-06-30 12:29:56 +02:00
2021-01-16 15:58:59 +01:00
| Name | Prefix | Action (A) | High context (HC) | Low context (LC) |
| ---------------------- | -------- | ---------- | ----------------- | ---------------- |
| `getPost` | | `get` | `Post` | |
| `getPostData` | | `get` | `Post` | `Data` |
| `handleClickOutside` | | `handle` | `Click` | `Outside` |
| `shouldDisplayMessage` | `should` | `Display` | `Message` | |
2017-06-30 10:24:03 +02:00
2021-01-16 15:58:59 +01:00
> **Note:** The order of context affects the meaning of a variable. For example, `shouldUpdateComponent` means _you_ are about to update a component, while `shouldComponentUpdate` tells you that _component_ will update on itself, and you are but controlling whether it should do that right now.
> In other words, **high context emphasizes the meaning of a variable**.
2017-06-30 11:53:09 +02:00
2018-05-10 10:19:49 +02:00
---
2017-12-20 11:31:12 +01:00
## Actions
2018-09-13 10:28:54 +02:00
2021-01-16 15:58:59 +01:00
The verb part of your function name. The most important part responsible for describing what the function _does_.
2017-06-30 13:46:30 +02:00
2018-09-13 10:31:18 +02:00
### `get`
2018-12-10 10:14:57 +01:00
2017-12-20 11:31:12 +01:00
Accesses data immediately (i.e. shorthand getter of internal data).
2021-01-16 15:58:59 +01:00
2017-06-30 10:24:03 +02:00
```js
function getFruitsCount() {
2021-01-16 15:58:59 +01:00
return this.fruits.length
2017-06-30 10:24:03 +02:00
}
```
2017-06-30 13:46:30 +02:00
2018-09-13 10:47:54 +02:00
> See also [compose](#compose).
2018-09-13 10:31:18 +02:00
### `set`
2018-12-10 10:14:57 +01:00
2018-04-19 10:54:35 +02:00
Declaratively sets a variable with value `A` to value `B`.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
2018-09-13 10:28:54 +02:00
const fruits = 0
2017-06-30 10:24:03 +02:00
2017-06-30 14:02:58 +02:00
function setFruits(nextFruits) {
2018-09-13 10:28:54 +02:00
fruits = nextFruits
2017-06-30 10:24:03 +02:00
}
2017-06-30 14:02:58 +02:00
2018-09-13 10:28:54 +02:00
setFruits(5)
2018-01-12 09:59:02 +01:00
console.log(fruits) // 5
2017-06-30 10:24:03 +02:00
```
2017-06-30 13:46:30 +02:00
2018-09-13 10:31:18 +02:00
### `reset`
2018-12-10 10:14:57 +01:00
2018-04-14 10:10:09 +02:00
Sets a variable back to its initial value or state.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
2018-09-13 10:28:54 +02:00
const initialFruits = 5
const fruits = initialFruits
setFruits(10)
console.log(fruits) // 10
2017-06-30 10:24:03 +02:00
function resetFruits() {
2018-09-13 10:28:54 +02:00
fruits = initialFruits
2017-06-30 10:24:03 +02:00
}
2018-09-13 10:28:54 +02:00
resetFruits()
console.log(fruits) // 5
2017-06-30 10:24:03 +02:00
```
2017-06-30 13:46:30 +02:00
2018-09-13 10:31:18 +02:00
### `fetch`
2018-12-10 10:14:57 +01:00
2018-05-10 10:19:49 +02:00
Requests for a data, which takes time (i.e. async request).
2021-01-16 15:58:59 +01:00
2018-05-10 10:19:49 +02:00
```js
function fetchPosts(postCount) {
2018-09-13 10:47:54 +02:00
return fetch('https://api.dev/posts', {...})
2018-05-10 10:19:49 +02:00
}
```
2018-09-13 10:31:18 +02:00
### `remove`
2018-12-10 10:14:57 +01:00
2021-01-16 15:58:59 +01:00
Removes something _from_ somewhere.
2018-04-14 10:10:09 +02:00
For example, if you have a collection of selected filters on a search page, removing one of them from the collection is `removeFilter`, **not** `deleteFilter` (and this is how you would naturally say it in English as well):
2018-01-12 09:59:02 +01:00
2017-06-30 13:46:30 +02:00
```js
2018-09-13 10:47:54 +02:00
function removeFilter(filterName, filters) {
2021-01-16 15:58:59 +01:00
return filters.filter((name) => name !== filterName)
2017-06-30 13:46:30 +02:00
}
2018-09-13 10:47:54 +02:00
const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)
2017-06-30 13:46:30 +02:00
```
2018-09-13 10:47:54 +02:00
> See also [delete](#delete).
2018-09-13 10:31:18 +02:00
### `delete`
2018-12-10 10:14:57 +01:00
Completely erazes something from the realms of existence.
2018-01-12 09:59:02 +01:00
Imagine you are a content editor, and there is that notorious post you wish to get rid of. Once you clicked a shiny "Delete post" button, the CMS performed a `deletePost` action, **not** `removePost`.
2017-12-20 11:31:12 +01:00
```js
function deletePost(id) {
2021-01-16 15:58:59 +01:00
return database.find({ id }).delete()
2017-12-20 11:31:12 +01:00
}
```
2017-06-30 13:46:30 +02:00
2018-09-13 10:47:54 +02:00
> See also [remove](#remove).
2018-09-13 10:31:18 +02:00
### `compose`
2018-12-10 10:14:57 +01:00
2021-01-16 15:58:59 +01:00
Creates new data from the existing one. Mostly applicable to strings, objects, or functions.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
function composePageUrl(pageName, pageId) {
2018-09-13 10:28:54 +02:00
return `${pageName.toLowerCase()}-${pageId}`
2017-06-30 10:24:03 +02:00
}
```
2018-09-13 10:47:54 +02:00
> See also [get](#get).
2018-09-13 10:31:18 +02:00
### `handle`
2018-12-10 10:14:57 +01:00
Handles an action. Often used when naming a callback method.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
function handleLinkClick() {
2018-09-13 10:28:54 +02:00
console.log('Clicked a link!')
2017-06-30 10:24:03 +02:00
}
2018-09-13 10:28:54 +02:00
link.addEventListener('click', handleLinkClick)
2017-06-30 10:24:03 +02:00
```
2018-05-10 10:19:49 +02:00
---
2018-09-13 10:28:54 +02:00
## Context
A domain that a function operates on.
2021-01-16 15:58:59 +01:00
A function is often an action on _something_. It is important to state what is its operable domain, or at least an expected data type.
2018-09-13 10:40:14 +02:00
```js
/* 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())
}
```
2021-01-16 15:58:59 +01:00
> Some language-specific assumptions may allow omitting the context. For example, in JavaScript, it's common that `filter` operates on Array. Adding explicit `filterArray` would be unnecessary.
2018-09-13 10:40:14 +02:00
2021-01-16 17:24:31 +01:00
--
2018-09-13 10:28:54 +02:00
2017-06-30 11:53:09 +02:00
## Prefixes
2017-06-30 12:07:17 +02:00
Prefix enhances the meaning of a variable. It is rarely used in function names.
2018-09-13 10:28:54 +02:00
### `is`
2018-12-10 10:14:57 +01:00
Describes a characteristic or state of the current context (usually `boolean`).
2018-01-12 09:59:02 +01:00
2017-06-30 11:53:09 +02:00
```js
2018-09-13 10:28:54 +02:00
const color = 'blue'
2021-01-16 15:58:59 +01:00
const isBlue = color === 'blue' // characteristic
2018-09-13 10:28:54 +02:00
const isPresent = true // state
2017-06-30 11:53:09 +02:00
2017-12-20 11:31:12 +01:00
if (isBlue && isPresent) {
2018-09-13 10:28:54 +02:00
console.log('Blue is present!')
2017-06-30 11:53:09 +02:00
}
```
2018-09-13 10:28:54 +02:00
### `has`
2018-12-10 10:14:57 +01:00
Describes whether the current context possesses a certain value or state (usually `boolean`).
2018-01-12 09:59:02 +01:00
2017-06-30 12:07:17 +02:00
```js
/* Bad */
2021-01-16 15:58:59 +01:00
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0
2017-06-30 12:07:17 +02:00
/* Good */
2021-01-16 15:58:59 +01:00
const hasProducts = productsCount > 0
2017-06-30 12:07:17 +02:00
```
2018-09-13 10:28:54 +02:00
### `should`
2018-12-10 10:14:57 +01:00
Reflects a positive conditional statement (usually `boolean`) coupled with a certain action.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
2018-09-13 10:28:54 +02:00
function shouldUpdateUrl(url, expectedUrl) {
2021-01-16 15:58:59 +01:00
return url !== expectedUrl
2017-06-30 10:24:03 +02:00
}
```
2017-12-20 11:31:12 +01:00
2018-09-13 10:28:54 +02:00
### `min`/`max`
2021-01-16 15:58:59 +01:00
Represent minimum or maximum value. Used when describing boundaries or limits.
2018-01-12 10:14:24 +01:00
```js
2018-09-23 11:07:03 +02:00
/**
* Renders random amount of posts within
* the given min/max boundaries.
*/
function renderPosts(posts, minPosts, maxPosts) {
return posts.slice(0, randomBetween(minPosts, maxPosts))
2018-01-12 10:14:24 +01:00
}
```
2018-09-13 10:28:54 +02:00
### `prev`/`next`
2018-12-10 10:14:57 +01:00
Indicate the previous or the next state of a variable in the current context. Used when describing state transitions.
2018-01-12 09:59:02 +01:00
2017-12-20 11:31:12 +01:00
```jsx
function fetchPosts() {
2018-09-13 10:28:54 +02:00
const prevPosts = this.state.posts
2021-01-16 15:58:59 +01:00
2018-09-13 10:28:54 +02:00
const fetchedPosts = fetch('...')
2018-09-23 11:07:03 +02:00
const nextPosts = concat(prevPosts, fetchedPosts)
2017-12-20 11:31:12 +01:00
2018-09-23 11:07:03 +02:00
this.setState({ posts: nextPosts })
2017-12-20 11:31:12 +01:00
}
```
2021-01-16 17:24:31 +01:00
## Singular and Plurals
Like a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.
```js
/* Bad */
2021-01-16 15:58:59 +01:00
const friends = 'Bob'
const friend = ['Bob', 'Tony', 'Tanya']
/* Good */
2021-01-16 15:58:59 +01:00
const friend = 'Bob'
const friends = ['Bob', 'Tony', 'Tanya']
```