Перевод статьи A Useful Framework for Naming Your Classes, Functions, and Variables
Автор оригинала XOR
"В компьютерном программировании соглашение об именах — набор правил для выбора последовательности символов, которая будет использоваться для идентификаторов, которые обозначают переменные, типы, функции и другие объекты в исходном коде и документации." - Википедия
Придумывать названия сложно!
В этой статье мы сосредоточимся на методе именования (P)A/HC/LC для того, чтобы улучшить читаемость кода.
Эти рекомендации можно применить к любому языку программирования, в статье для примеров кода используется JavaScript.
В данной практике используется следующий шаблон для именования функции:
префикс? (P) + действие (A) + высокоуровневый контекст (HC) + низкоуровневый контекст? (LC)
Префикс расширяет смысл функции.
- is
Описывает свойство или состояние текущего контекста (обычно логическое значение).
const color = 'blue';
const isBlue = (color === 'blue'); // свойство
const isPresent = true; // состояние
if (isBlue && isPresent) {
console.log('Blue is present!');
}
- has
Указывает, имеет ли текущий контекст определенное значение или состояние (обычно логическое значение).
/* Плохо */
const isProductsExist = (productsCount > 0);
const areProductsPresent = (productsCount > 0);
/* Хорошо */
const hasProducts = (productsCount > 0);
- should
Отражает положительный условный оператор (обычно логическое значение), связанный с определенным действием.
function shouldUpdateUrl(url, expectedUrl) {
return (url !== expectedUrl);
}
Действие – это глагольная часть имени функции. Это самая важная часть в описании того, что делает функция.
- get
Получает доступ к данным немедленно (это сокращение от getter для внутренних данных).
function getFruitsCount() {
return this.fruits.length;
}
- set
Безусловно присваивает переменной со значением A значение B.
const fruits = 0;
function setFruits(nextFruits) {
fruits = nextFruits;
}
setFruits(5);
console.log(fruits); // 5
- reset
Возвращает переменную к её начальному значению или состоянию.
const initialFruits = 5;
const fruits = initialFruits;
setFruits(10);
console.log(fruits); // 10
function resetFruits() {
fruits = initialFruits;
}
resetFruits();
console.log(fruits); // 5
- fetch
Выполняет запрос данных, для которого требуется время (например, асинхронный запрос).
function fetchPosts(postCount) {
return fetch('https://api.dev/posts', {...});
}
- remove
Удаляет что-то откуда-то.
Например, если у вас есть коллекция выбранных фильтров на странице поиска, удаление одного из них из коллекции – это removeFilter
, а не deleteFilter
(именно так вы и скажете на английском языке):
function removeFilter(filterName, filters) {
return filters.filter(name => name !== filterName);
}
const selectedFilters = ['price', 'availability', 'size'];
removeFilter('price', selectedFilters);
- delete
Полностью стирает что-то. После операции сущность перестаёт существовать.
Представьте, что вы редактор контента, и есть пост, от которого вы хотите избавиться. Как только вы нажали на кнопку delete-post, CMS выполнила действие deletePost
, а не removePost
.
function deletePost(id) {
return database.find({ id }).delete();
}
- compose
Создает новые данные из существующих. Обычно это применимо к строкам, объектам или функциям.
function composePageUrl(pageName, pageId) {
return `${pageName.toLowerCase()}-${pageId}`;
}
- handle
Обработка действия. Часто используется при именовании обратного вызова.
function handleLinkClick() {
console.log('Clicked a link!');
}
link.addEventListener('click', handleLinkClick);
Контекст – это область, с которой работает функция.
Функция – это часто действие с чем-то. Важно указать, какова её рабочая область или, по крайней мере, ожидаемый тип данных.
/* Чистая функция, работающая с примитивами */
function filter(predicate, list) {
return list.filter(predicate);
}
/* Функция, работающая непосредственно с сообщениями */
function getRecentPosts(posts) {
return filter(posts, (post) => post.date === Date.now());
}
/*
Некоторые специфические для языка допущения позволяют опустить контекст.
Например, в JavaScript фильтр обычно работает с массивом (Array).
Добавление явного filterArray будет избыточным.
*/
Имя функции | Префикс (P) | Действие (A) | Высокий контекст (HC) | Низкий контекст (LC) |
---|---|---|---|---|
getUser |
get |
User |
||
getUserMessages |
get |
User |
Messages |
|
handleClickOutside |
handle |
Click |
Outside |
|
shouldDisplayMessage |
should |
Display |
Message |
В этом разделе мы предложим некоторые правила именования переменных, которые улучшат читаемость кода.
Имя должно быть коротким (Short), интуитивно понятным (Intuitive) и описательным (Descriptive).
/* Плохо */
const a = 5; // "a" может обозначать что угодно
const isPaginatable = (postsCount > 10); // "Paginatable" звучит крайне неестественно
const shouldPaginatize = (postsCount > 10); // Придуманные глаголы - это так весело!
/* Хорошо */
const postsCount = 5;
const hasPagination = (postsCount > 10);
const shouldDisplayPagination = (postsCount > 10); // альтернатива
Не используйте сокращения. Обычно они только ухудшают читаемость кода. Найти короткое, описательное имя может быть сложно, но сокращения не могут быть оправданием для того, чтобы этого не делать. Например:
/* Плохо */
const onItmClk = () => {};
/* Хорошо */
const onItemClick = () => {};
Всегда удаляйте контекст из имени, если это не снижает его читабельность.
class MenuItem {
/* Имя метода дублирует контекст (которым является "MenuItem") */
handleMenuItemClick = (event) => { ... };
/* Читается как `MenuItem.handleClick()` */
handleClick = (event) => { ... };
}
/* Плохо */
const isEnabled = (itemsCount > 3);
return <Button disabled={!isEnabled} />;
/* Хорошо */
const isDisabled = (itemsCount <= 3);
return <Button disabled={isDisabled} />;
Как и префикс, имена переменных могут быть единственного или множественного числа в зависимости от того, имеют ли они одно значение или несколько.
/* Плохо */
const friends = 'Bob';
const friend = ['Bob', 'Tony', 'Tanya'];
/* Хорошо */
const friend = 'Bob';
const friends = ['Bob', 'Tony', 'Tanya'];
/* Просто ужасно */
const yyyymmdstr = moment().format("YYYY/MM/DD");
/* Гораздо лучше */
const currentDate = moment().format("YYYY/MM/DD");
Эти рекомендации можно применить к любому языку программирования, в статье для примеров кода используется JavaScript.
Предлагаю оставить мой вариант -> Действие - это сердце функции.
Так получается больший акцент на важности этого элемента.
У автора: Declaratively sets a variable with value A to value B.
Предлагаю так: Безусловно присваивает переменной со значением A значение B.
Declaratively - Безусловно -> это важно!
Вместо "присваивает" можно использовать "устанавливает". На мой взгляд "присваивает" - звучит по-русски, а "устанавливает" - дословный перевод английского слова "set"
Выполняет запрос данных для которго требуется время (например, асинхронный запрос).
Вы убрали "тот пресловутый", тогда надо убрать и "блестящую".
Тут автор добравил эмочиональны окрас. Надо либо сухо поделовому, либо полностью с эмоциями.
Тут с Вами не соглашусь. Имя может быть осмысленным, но, при этом, непроизносимым.
И ещё один момент:
У автора в конце сслыка: This writing was inspired by this GitHub repo. https://github.com/kettanaito/naming-cheatsheet
Считаю её надо оставить. Я просто упустил.