naming-cheatsheet/README.md

303 lines
7.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
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
Pick **one** naming convention and follow it. It may be `likeThis`, or `like_this`, 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
A name must be *short*, *intuitive* and *descriptive*:
* **Short**. A name must not take long to type and, therefore, to remember,
* **Intuitive**. Name must read naturally, as close to the common speach as possible
* **Descriptive**. 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
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
2018-09-13 10:40:14 +02: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
Do **not** use contractions. They contribute to nothing but decreased readability of your code. Finding a short, descriptive name may be hard, but contraction is not an excude to 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) => { ... }
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 */
2018-09-13 10:28:54 +02:00
const isEnabled = (itemsCount > 3)
return <Button disabled={!isEnabled} />
2017-06-30 10:49:04 +02:00
/* Good */
2018-09-13 10:28:54 +02:00
const isDisabled = (itemsCount <= 3)
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
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-01-12 09:59:02 +01:00
To illustrate, take a look at how this pattern may be applied in the table below.
2017-06-30 12:29:56 +02:00
2017-06-30 10:40:36 +02:00
| Name | Prefix | Action | High context | Low context |
| ---- | ---- | ------ | ------------ | ----------- |
| `getPost` | | `get` | `Post` | |
| `getPostData` | | `get` | `Post` | `Data` |
| `handleClickOutside` | | `handle` | `Click` | `Outside` |
2017-06-30 10:55:43 +02:00
| `shouldDisplayMessage` | `should` | `Display` | `Message`| |
2017-06-30 10:24:03 +02:00
2018-09-13 10:28:54 +02:00
> **Note:** Context order affects the meaning of a method. 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
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`
2017-12-20 11:31:12 +01:00
Accesses data immediately (i.e. shorthand getter of internal data).
2017-06-30 10:24:03 +02:00
```js
function getFruitsCount() {
2017-08-15 11:41:34 +02: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-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-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-05-10 10:19:49 +02:00
Requests for a data, which takes time (i.e. async request).
```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-04-14 10:10:09 +02:00
Removes something *from* somewhere.
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) {
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-01-12 09:59:02 +01:00
Completely erazes something from the realms of existance.
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) {
2018-09-13 10:28:54 +02: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-04-14 10:10:09 +02:00
Creates a new data from the existing one. Mostly applicable to strings or objects.
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`
2017-12-20 11:31:12 +01:00
Handles a dedicated action. Often used in naming the callback methods.
2018-01-12 09:59:02 +01:00
2017-06-30 10:24:03 +02:00
```js
function handleLinkClick(event) {
2018-09-13 10:28:54 +02:00
event.preventDefault()
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.
2018-09-13 10:40:14 +02: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.
```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())
}
```
> Note that language-specific assumptions may allow to ommit the context in some cases. For example, in JavaScript it is common that `filter` operates on Array. Adding explicit `filterArray` would be unnecessary.
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
2018-09-13 10:28:54 +02:00
Prefix enhances the meaning of a variable.
### `is`
Describes certain characteristic or state of the current context (returns `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'
const isBlue = (color === 'blue') // characteristic
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`
Describes whether the current context possesses a certain value or state (returns `boolean`).
2018-01-12 09:59:02 +01:00
2017-06-30 12:07:17 +02:00
```js
/* Bad */
2018-09-13 10:28:54 +02:00
const isProductsExist = (productsCount > 0)
const areProductsPresent = (productsCount > 0)
2017-06-30 12:07:17 +02:00
/* Good */
2018-09-13 10:28:54 +02:00
const hasProducts = (productsCount > 0)
2017-06-30 12:07:17 +02:00
```
2018-09-13 10:28:54 +02:00
### `should`
2018-01-12 09:59:02 +01:00
Reflects a positive conditional statement (returns `Boolean`) tightly coupled with a certain action.
2017-06-30 10:24:03 +02:00
```js
2018-09-13 10:28:54 +02:00
function shouldUpdateUrl(url, expectedUrl) {
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`
Represent minimum or maximum value. Useful for describing boundaries or limits.
2018-01-12 10:14:24 +01:00
```js
function PostsList() {
2018-09-13 10:28:54 +02:00
this.minPosts = 3
this.maxPosts = 10
2018-01-12 10:14:24 +01:00
}
```
2018-09-13 10:28:54 +02:00
### `prev`/`next`
2018-04-19 10:54:35 +02:00
Indicate the previous and the next state of a variable in the current context. Useful for 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
2017-12-20 11:31:12 +01:00
2018-09-13 10:28:54 +02:00
const fetchedPosts = fetch('...')
const nextPosts = prevPosts.merge(fetchedPosts)
2017-12-20 11:31:12 +01:00
2018-09-13 10:28:54 +02:00
return this.setState({ posts: nextPosts })
2017-12-20 11:31:12 +01:00
}
```