Skip to content

Instantly share code, notes, and snippets.

@zhabinka
Forked from AABur/naming.md
Last active May 12, 2021 08:51
Show Gist options
  • Save zhabinka/97c075d482dfcd090d3dc21d37de9ef0 to your computer and use it in GitHub Desktop.
Save zhabinka/97c075d482dfcd090d3dc21d37de9ef0 to your computer and use it in GitHub Desktop.

Практичная структура для именования классов, функций и переменных

Перевод статьи A Useful Framework for Naming Your Classes, Functions, and Variables

Автор оригинала XOR

"В компьютерном программировании соглашение об именах — набор правил для выбора последовательности символов, которая будет использоваться для идентификаторов, которые обозначают переменные, типы, функции и другие объекты в исходном коде и документации." - Википедия

Придумывать названия сложно!

В этой статье мы сосредоточимся на методе именования (P)A/HC/LC для того, чтобы улучшить читаемость кода.

Эти рекомендации можно применить к любому языку программирования, в статье для примеров кода используется JavaScript.

Что значит (P)A/HC/LC?

В данной практике используется следующий шаблон для именования функции:

префикс? (P) + действие (A) + высокоуровневый контекст (HC) + низкоуровневый контекст? (LC)

Что обозначает Префикс (P)?

Префикс расширяет смысл функции.

- 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

Пять принципов именования переменных

В этом разделе мы предложим некоторые правила именования переменных, которые улучшат читаемость кода.

1. Следуйте S-I-D

Имя должно быть коротким (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); // альтернатива

2. Избегайте сокращений

Не используйте сокращения. Обычно они только ухудшают читаемость кода. Найти короткое, описательное имя может быть сложно, но сокращения не могут быть оправданием для того, чтобы этого не делать. Например:

    /* Плохо */
    const onItmClk = () => {};

    /* Хорошо */
    const onItemClick = () => {};

3. Избегайте дублирования контекста

Всегда удаляйте контекст из имени, если это не снижает его читабельность.

    class MenuItem {
    /* Имя метода дублирует контекст (которым является "MenuItem") */
    handleMenuItemClick = (event) => { ... };

    /* Читается как `MenuItem.handleClick()` */
    handleClick = (event) => { ... };
    }

4. Отражайте в имени ожидаемый результат

    /* Плохо */
    const isEnabled = (itemsCount > 3);
    return <Button disabled={!isEnabled} />;

    /* Хорошо */
    const isDisabled = (itemsCount <= 3);
    return <Button disabled={isDisabled} />;

5. Учитывайте единственное/множественное число

Как и префикс, имена переменных могут быть единственного или множественного числа в зависимости от того, имеют ли они одно значение или несколько.

    /* Плохо */
    const friends = 'Bob';
    const friend = ['Bob', 'Tony', 'Tanya'];

    /* Хорошо */
    const friend = 'Bob';
    const friends = ['Bob', 'Tony', 'Tanya'];

6. Используйте осмысленные и произносимые имена

    /* Просто ужасно */
    const yyyymmdstr = moment().format("YYYY/MM/DD");

    /* Гораздо лучше */
    const currentDate = moment().format("YYYY/MM/DD");
@AABur
Copy link

AABur commented May 9, 2021

Эти рекомендации можно применить к любому языку программирования, но мы будем использовать JavaScript, чтобы проиллюстрировать их на практике.

Эти рекомендации можно применить к любому языку программирования, в статье для примеров кода используется JavaScript.

Действие - сердце функции

Предлагаю оставить мой вариант -> Действие - это сердце функции.
Так получается больший акцент на важности этого элемента.

Устанавливает значение переменной из A в B.

У автора: Declaratively sets a variable with value A to value B.
Предлагаю так: Безусловно присваивает переменной со значением A значение B.
Declaratively - Безусловно -> это важно!
Вместо "присваивает" можно использовать "устанавливает". На мой взгляд "присваивает" - звучит по-русски, а "устанавливает" - дословный перевод английского слова "set"

Запрашивает данные, требуя время на исполнение (например, асинхронный запрос).

Выполняет запрос данных для которго требуется время (например, асинхронный запрос).

Представьте, что вы редактор контента, и есть тот пресловутый пост, от которого вы хотите избавиться. Как только вы нажали на блестящую кнопку delete-post, CMS выполнила действие deletePost, а не removePost.

Вы убрали "тот пресловутый", тогда надо убрать и "блестящую".
Тут автор добравил эмочиональны окрас. Надо либо сухо поделовому, либо полностью с эмоциями.

  1. Используйте осмысленные и произносимые имена переменных

Тут с Вами не соглашусь. Имя может быть осмысленным, но, при этом, непроизносимым.

И ещё один момент:
У автора в конце сслыка: This writing was inspired by this GitHub repo. https://github.com/kettanaito/naming-cheatsheet
Считаю её надо оставить. Я просто упустил.

@zhabinka
Copy link
Author

Ага, спасибо! Поправил текст.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment