Перевод Naming cheatsheet
- Английский язык
- Соглашение об именовании (Naming convention)
- S-I-D
- Избегайте сокращений
- Избегайте дублирования контекста
- Отразить ожидаемый результат
- Именование функций
- Единственное и множественное число
Называть вещи сложно. Этот руководство должно помочь сделать это проще.
Хотя эти предложения можно применить к любому языку программирования, я буду использовать JavaScript, чтобы проиллюстрировать их на практике.
Используйте английский язык при именовании переменных и функций.
/* Bad */
const primerNombre = 'Gustavo';
const amigos = ['Kate', 'John'];
/* Good */
const firstName = 'Gustavo';
const friends = ['Kate', 'John'];
Нравится вам это или нет, но английский является доминирующим языком в программировании: на английском написан синтаксис всех языков программирования, а также бесчисленное множество документации и учебных материалов. Написав код на английском языке, вы значительно повысите его связность.
В JavaScript для именования переменных и функций используется camelCase
нотация, для классов и функций-конструкторов PascalCase
нотация.
/* Bad */
const page_count = 5;
const ShouldUpdate = true;
class appLogger {};
/* Good */
const pageCount = 5;
const shouldUpdate = true;
class AppLogger {};
Имя должно быть коротким, интуитивным и описательным (short, intuitive, descriptive):
- Короткий. Имя не должно занимать много времени, чтобы набираться и, следовательно, запоминаться;
- Интуитивный. Имя должно читаться естественно, как можно ближе к обычной речи;
- Описательный. Имя должно наиболее эффективно отражать то, что оно делает/чем обладает.
/* Bad */
const a = 5; // "a" может означать что угодно
const isPaginatable = a > 10; // "Paginatable" звучит крайне неестественно
const shouldPaginatize = a > 10; // Придуманные глаголы — это так весело!
/* Good */
const postCount = 5;
const hasPagination = postCount > 10;
const shouldPaginate = postCount > 10; // альтернатива
Не используйте сокращения. Они не способствуют ничему, кроме снижения читабельности кода. Найти короткое, описательное имя может быть сложно, но сокращение не является оправданием для отказа от этого.
/* Bad */
const onItmClk = () => {};
/* Good */
const onItemClick = () => {};
Имя не должно дублировать контекст, в котором оно определено. Всегда удаляйте контекст из имени, если это не ухудшает его читабельность.
class MenuItem {
/* Bad: Имя метода дублирует контекст (который "MenuItem") */
handleMenuItemClick = (event) => { ... };
/* Good: Читается хорошо, как `MenuItem.handleClick()` */
handleClick = (event) => { ... };
}
Имя должно отражать ожидаемый результат.
/* Bad */
const isEnabled = itemCount > 3;
return <Button disabled={!isEnabled} />;
/* Good */
const isDisabled = itemCount <= 3;
return <Button disabled={isDisabled} />;
Существует полезный шаблон, которому следует следовать при именовании функций:
prefix? + action (A) + high context (HC) + low context? (LC)
Посмотрите, как можно применить этот шаблон, в таблице ниже.
Name | Prefix | Action (A) | High context (HC) | Low context (LC) |
---|---|---|---|---|
getUser |
get |
User |
||
getUserMessages |
get |
User |
Messages |
|
handleClickOutside |
handle |
Click |
Outside |
|
shouldDisplayMessage |
should |
Display |
Message |
Примечание. Порядок контекста влияет на значение переменной. Например,
shouldUpdateComponent
означает, что вы собираетесь обновить компонент, аshouldComponentUpdate
сообщает вам, что comComponent обновит себя, и вы контролируете только когда он должен обновиться. Другими словами, High context (HC) подчеркивает значение переменной.
Глагольная часть имени вашей функции. Самая важная часть, отвечающая за описание того, что делает функция.
Немедленный доступ к данным (т. е. сокращенный метод получения внутренних данных).
function getFruitCount() {
return this.fruits.length;
}
Смотрите также compose.
Вы также можете использовать get
при выполнении асинхронных операций:
async function getUser(id) {
return await fetch(`/api/user/${id}`);
}
Устанавливает переменную декларативным способом со значением A
в значение B
.
let fruits = 0;
function setFruits(nextFruits) {
fruits = nextFruits;
}
setFruits(5);
console.log(fruits); // 5
Возвращает переменную в исходное значение или состояние.
const initialFruits = 5;
let fruits = initialFruits;
setFruits(10);
console.log(fruits); // 10
function resetFruits() {
fruits = initialFruits;
}
resetFruits();
console.log(fruits); // 5
Удаляет что-то _от_куда-то.
Например, если у вас есть коллекция выбранных фильтров на странице поиска, удаление одного из них из коллекции - это removeFilter
, а не deleteFilter
(и именно так вы, естественно, скажете это и на английском языке):
function removeFilter(filterName, filters) {
return filters.filter((name) => name !== filterName);
}
const selectedFilters = ['price', 'availability', 'size'];
removeFilter('price', selectedFilters);
Смотрите также delete.
Полностью стирает что-то из сфер существования.
Представьте, что вы редактор контента, и есть пресловутый пост, от которого вы хотите избавиться.
После того, как вы нажали блестящую кнопку «Удалить сообщение», CMS выполнила действие deletePost
, а не removePost
.
function deletePost(id) {
return database.find({ id }).delete();
}
Смотрите также remove.
remove
ordelete
? Если разница междуremove
иdelete
для вас не столь очевидна, я бы предложил взглянуть на их противоположные действия -add
иcreate
. Ключевое различие междуadd
иcreate
заключается в том, чтоadd
требует назначения, аcreate
не требует места назначения. Выдобавляете
элемент куда-то, но не "создаете
его куда-то". Просто соединитеremove
сadd
иdelete
сcreate
.Подробно объяснено здесь (анг).
Создает новые данные из существующих. В основном применимо к строкам, объектам или функциям.
function composePageUrl(pageName, pageId) {
return pageName.toLowerCase() + '-' + pageId;
}
Смотрите также get.
Обрабатывает действие. Часто используется при названии метода обратного вызова.
function handleLinkClick() {
console.log('Clicked a link!');
}
link.addEventListener('click', handleLinkClick)
Домен, в котором работает функция.
Функция часто представляет собой действие над чем-то. Важно указать, какова его рабочая область или, по крайней мере, ожидаемый тип данных.
/* Чистая функция, работающая с примитивами */
function filter(list, predicate) {
return list.filter(predicate);
}
/* Функция, работающая именно с постами */
function getRecentPosts(posts) {
return filter(posts, (post) => post.date === Date.now());
}
Некоторые предположения, специфичные для языка, могут позволить опустить контекст. Например, в JavaScript обычно
filter
работает с массивом. Добавление явногоfilterArray
было бы ненужным.
Префикс расширяет значение переменной. Он редко используется в именах функций (практически никогда).
Описывает характеристику или состояние текущего контекста (обычно логическое значение boolean
).
const color = 'blue';
const isBlue = color === 'blue'; // характеристика
const isPresent = true; // состояние
if (isBlue && isPresent) {
console.log('Blue is present!');
}
Описывает, обладает ли текущий контекст определенным значением или состоянием (обычно логическое значение boolean
).
/* Bad */
const isProductsExist = productsCount > 0;
const areProductsPresent = productsCount > 0;
/* Good */
const hasProducts = productsCount > 0;
Отражает положительное условное утверждение (обычно логическое boolean
), связанное с определенным действием.
function shouldUpdateUrl(url, expectedUrl) {
return url !== expectedUrl;
}
Представляет минимальное или максимальное значение. Используется при описании границ или пределов.
/**
* Отображает случайное количество сообщений внутри
* заданных границы мин/макс.
*/
function renderPosts(posts, minPosts, maxPosts) {
return posts.slice(0, randomBetween(minPosts, maxPosts));
}
Укажите предыдущее или следующее состояние переменной в текущем контексте. Используется при описании переходов состояний.
async function getPosts() {
const prevPosts = this.state.posts;
const latestPosts = await fetch('...');
const nextPosts = concat(prevPosts, latestPosts);
this.setState({ posts: nextPosts });
}
Как и префикс, имена переменных могут быть записаны в единственном или множественном числе в зависимости от того, содержат ли они одно или несколько значений.
/* Bad */
const friends = 'Bob';
const friend = ['Bob', 'Tony', 'Tanya'];
/* Good */
const friend = 'Bob';
const friends = ['Bob', 'Tony', 'Tanya'];