Стандарты написания кода “Лэйзи Энд Фокусед”
“Лень подчинила себе процессы, пока мы фокусировались на обязанностях”
— Valentin Bird ~ придумано за минуту.
“Код, придерживающийся единой концепции и стиля, — элегантный”
— FOCKUSTY ~ красота всему голова.
Правила “простого кода” по Роберту Мартину:
- Проходит все тесты
- Не содержит дубликатов
- Выражает все концепции системы
- Не содержит лишний сущностей.
1. Наименование
- Использовать определенную нотацию в соответствии с языком программирования.
JSON—camelCase.Database—snake_case.
- Использовать в названиях аббревиатуры как одно слово.
camelCase—getApiUrl.snake_case—get_api_url.kebab-case—get-api-url.- И их аналоги (
UpperCamelCase,SCREAMING_SNAKE_CASE,camel-Kebab-Caseи др).
- Наименование должно отражать то, что оно делает.
- Наименование не должно содержать артиклей.
- Наименование не должно содержать дезинформации.
- Желательно избегать сокращений, исключение
составляет общепринятая нотация, например:
i,j,kв циклах, но даже их лучше писать полностью при возможности. Поясните! - Желательно использовать удобно произносимые наименования.
- Нежелательно добавлять избыточный контекст в наименования.
- Обязательно именовать классы, типы и интерфейсы в
UpperCamelCase. - Обязательно именовать на английском языке, транслит запрещается.
- Обязательно именовать константы в
SCREAMING_SNAKE_CASE. - Обязательно именовать в американском английском диалекте.
2. Переменные и поля
- Объявление данных ближе к контексту (Объявите переменную близко к тому, где она используется).
- Если переменное/поле содержит булево значение, то наименование должно содержать прошедшее время:
actived,available,outdated. Если это невозможно, то добавляйтесь префикс is:isAdmin,isUser.
3. Функции и методы
- Имя функции должно содержать глагольную часть.
- Каждая линия функции должна быть на одинаковом уровне абстракции. Поясните!
- Функция должна делать только одно действие.
- Функция должна принимать не более трёх аргументов.
- Функция не должна быть больше 100 строк, оптимальная длина: 20-30 строк — вся функция должна умещаться на экране.
- Функция не должна изменять состояние параметров, которое ей было передано.
- Функция не должна возвращать
nullилиundefined, когда это не предусмотрено логикой, желательно возвращать ошибку (throw new error) илиfalse, если логика позволяет. - Функция не должна возвращать код ошибки.
- Функции желательно проверять параметры и возвращаемые значения.
- Функции нежелательно принимать булев аргумент.
- Желательно избегать рекурсии в функциях.
- Если из функции можно извлечь функцию, то нужно извлечь.
- Если функция возвращает булево значение, то наименование должно содержать вопрос:
isActive,isAvailable. Если наименование содержит существительное, то добавляйте префиксvalidateк наименованию:validateAdmin,validateUser. - Если функция выступает в роли обработчика событий, то наименование должно содержать префикс
on:onClick,onMove.
4. Классы
- Имена классов не должно содержать глагольную часть, так как оно должно представлять собой существительные и их комбинации.
- Модификаторы доступа у полей по умолчанию:
private. - Обязательно наименование класса в
UpperCamelCaseили в соответствии с языком программирования. - Обязательно инициализация поля в конструкторе.
- Обязательно использовать единый стиль исполняющего методова, в зависимости от проекта. По умолчанию:
execute. Возможные варианты:execute,run,initialize(init). - Методы класса не должны быть объявлены через лямбда-синтаксис. Чё?
5. Циклы
- Циклы должны содержать определенное количество итераций.
6. Импорт и экспорт
- Нельзя импортировать и экспортировать одновременно. Поясните!
- Импортировать типы/абстракцию как типы. Не понял
- Всегда экспортировать дефолтный экспорт вместе с недефолтным (имеются исключения из-за фреймворков).
- Всегда выносить импорт типов.
- Избегать
require. - Избегать
import * as {name}. - Обязательно сортировать импорты.
- Также импортировать сначала типы (типы, интерфейсы, абстракные классы)
- После данные (функции, переменные, классы)
- А в конце вспомогательные файлы (
.txt,.json,.css) и импорты-инициализаторы (за редким исключением). Ничего не понял, но очень интересно
- Если есть возможность импортировать статично, то нужно импортировать статично.
7. Код
- Извлекайте функции.
- Переименовывайте в поиске лучшего названия.
- Удаляйте дубликаты кода.
- Снижайте уровень вложенности кода.
- Используйте пояснительные переменные. Поясните!
- Код не должен содержать лишнии комментарии (Разрешается писать документацию через специальные комментарии).
- Код не должен содержать закомментированный код.
- Код не должен содержать магический чисел, строк…
- Желательно не опускать фигурные скобки. Поясните!
- Желательно иметь маленький уровень табуляции (идентации).
- Уровень табуляции зависит от проекта. Стандартный уровень табуляции в команде: 2 пробела.
8. Компиляция
- Желательно компилировать код, находящийся в разработке, каждый день для проверки на ошибки.
Пояснения
Если используете сокращения, то используйте их во всём коде одинаково.
-
1.6. “Желательно избегать сокращений, исключение составляет общепринятая нотация…” — Все допустимые сокращения:
- add — addition.
- app — application.
- arr — array.
- asc — ascending.
- auth — authentication.
- bool — boolean.
- cfg/config — configuration.
- char — character.
- const — constant.
- desc — descending.
- dev — development.
- dir — directory.
- env — environment.
- func — function.
- id — identifier.
- img — image.
- init — initialize.
- int — integer.
- max — maximum.
- min — minimum.
- msg — message.
- nav — navigation.
- num — number.
- obj — object.
- req — request.
- res — response.
- rm/rem — remove.
- src — source.
- temp — temporary.
- up — update.
- var — variable.
Также допускается использование метапеременных из математики: a, b, c, d, e, f; x, y, z, w; i, j, k.
И мета-чисел: 23, 42, 47, 69, 666, 0815, 1337, 4711.
Также допускается сокращения до одной буквы, когда используются методы массивов/объектов/…, например:const numbers = [1, 2, 3, 4, 5, 6]; const otherNumber = numbers.map((n) => n * 2);Но только тогда и только тогда, когда переменная понятна из контекста и код не выглядит большим и громовским. Давай обратно!
-
3.2. “Каждая линия функции должна быть на одинаковом уровне абстракции” — Каждая часть функции должна, как и функция, выполнять работу над действием функции. Хочу назад!
-
4.6.
// Так нельзя class ExampleClass { hello = () => { console.log(); } } // Так можно class ExampleClass { hello() { console.log(); } } -
6.1.
export import("some-path"); -
6.2.
import type { SomeClass, SomeType, SomeInterface } from "path-to"; // SomeType и SomeInteraface всегда импортируются, как типы // SomeClass только в том случае, если он используется, как тип -
6.7.
import "dotenv/config"; // init-импорт, который обязательно должен быть в начале import type { SomeType, SomeInteraface } from "path-to"; import { SomeClass, SOME_CONTENT } from "path2"; import package from "package.json"; import "style.css"; -
7.5. “Использовать пояснительные переменные” — Объявлять переменные, когда записываешь условие или результат функции.
const transferAllowed = hasSufficientBalance(account.balance, transfer.amount) && account.isActive(); if (transferAllowed) { console.log("Transfer successful."); } else { throw new Error("Transfer can not be completed."); } -
7.9. “Желательно не опускать фигурные скобки” — см. снимок экрана.
// Без опускания фигурных скобок if (transferAllowed) { console.log("Transfer successful."); } else { throw new Error("Transfer can not be completed."); } // С опусканием фигурных скобок if (transferAllowed) console.log("Transfer successful."); else throw new Error("Transfer can not be completed.");При этом допускается опускание скобок, если сразу после идёт возврат функции или вброс ошибки (заканчивание логики). Хорошо!
Источники вдохновения
- Книга “Чистый код” — Роберт Мартин.
- YouTube-видео “Как писать чистый код” — Vlad Mishustin.
- YouTube-видео “Пиши код как NASA” — Си-шный Поц.
- YouTube-видео “Правила написания кода от Дяди Боба” — Си-шный Поц.