Культура кода — итоги
Структуры в коде — Структуры данных; persistence — ORM.
Кратко — что стоит унести из раздела "Культура кода". Если пункт кажется туманным — откройте указанную главу или оглавление. Базовая теория терминов (синтаксис, рефакторинг, исключения) — 4.02 Код, методы рефакторинга. Определения для самопроверки — в чек-листе.
FAQ — Часто задаваемые вопросы
Типичные ситуации на первой работе и в ревью — споры о стиле, "красный" линтер, перегруженные методы. Здесь — что делать на практике; формулировки для зачёта — в чек-листе.
Вопрос. Ревьюер просит переименовать половину переменных — это про культуру или про личный вкус?
Ответ. Если имена нарушают соглашения проекта или скрывают смысл (data, temp) — это культура. Если спор только о синониме (user vs client) при едином стиле — зафиксируйте правило в глоссарии или style guide, а не в каждом PR. Подробнее здесь — глава 1.
Вопрос. Первый PR упал на CI из‑за линтера — можно "попросить отключить правило"?
Ответ. Сначала прогоните форматтер и линтер локально — это часть культуры, а не "мелочь CI". Отключение правила без обсуждения команды создаёт прецедент. Если правило реально мешает — предложите изменение конфига в отдельном PR. Подробнее здесь — глава 1.
Вопрос. Коллега пишет иначе, чем в учебнике — кто прав?
Ответ. В команде важнее единый стиль репозитория, чем "идеальный" учебник. Смотрите .editorconfig, eslint/prettier, существующий код в том же модуле. Спор — повод обновить документ команды, а не переписывать чужой PR целиком. Подробнее здесь — глава 1.
Вопрос. Когда писать комментарий, а когда просто переименовать переменную?
Ответ. Если смысл виден из имени и структуры — переименуйте. Комментарий нужен для "почему" (бизнес-ограничение, баг API, legacy), а не для пересказа цикла for. Устаревший комментарий хуже отсутствующего. Подробнее здесь — глава 1.
Вопрос. PR вернули с формулировкой "слишком сложно" — с чего начать правку?
Ответ. Посмотрите цикломатическую сложность и вложенность: часто помогает ранний выход, вынос веток в именованные методы по смыслу (SRP), а не механическое "разбить на десять функций". Подробнее здесь — глава 2.
Вопрос. В legacy-коде везде "магические" числа — трогать при своей задаче?
Ответ. В рамках своей правки — локально вынесите константу с говорящим именем, если понимаете смысл. Массовый рефакторинг без тестов рискован; большой объём — отдельный PR или техдолг-тикет. Подробнее здесь — глава 1, глава 10.
Вопрос. Две функции почти одинаковые — обязательно выносить в общую?
Ответ. Не всегда: дублирование знания (одна формула в двух местах) опасно; два похожих блока ради читаемости в одном файле иногда допустимы. Спросите: изменится ли бизнес-правило в обоих местах одновременно? Подробнее здесь — глава 1.
Вопрос. Нужна фича, но код вокруг "грязный" — рефакторить в том же PR?
Ответ. Мелкая уборка на пути к фиче — нормально; большой рефакторинг лучше отдельным PR, чтобы ревью видело риск и откат был проще. Подробнее здесь — глава 10.
Вопрос. В проекте Singleton на каждый сервис — это нормально?
Ответ. Частый запах: скрытая глобальная связанность, сложные тесты, неочевидный порядок инициализации. Предпочитайте явную передачу зависимостей; если Singleton уже есть — не плодите новые без необходимости. Подробнее здесь — глава 9.
Вопрос. Метод на 80 строк из if (x != null) — как не утонуть?
Ответ. Сужайте контракт: fail fast на входе, явные типы вместо null где возможно, guard-clauses вместо пирамиды вложенности. Подробнее здесь — глава 8.
Вопрос. Sonar показывает "Critical", а тимлид говорит "мерджим" — кому верить?
Ответ. Метрики — повод для разговора, не автоматический запрет. Разберите конкретное замечание: реальный риск регресса или шум правила? Зелёный дашборд ради KPI без смысла — другая крайность. Подробнее здесь — глава 2, глава 10.
Вопрос. Старший прислал PR на 2500 строк — что делать ревьюеру?
Ответ. Вежливо попросите разбить или выделить логические коммиты; ориентир команды — порядка 200–400 строк. Большой diff повышает риск пропустить баг — это про безопасность, а не иерархию. Подробнее здесь — глава 10.
Вопрос. Имена только на английском, а домен на русском — путаница в голове.
Ответ. Заведите глоссарий: Order = заказ, Contract = договор. В коде — один язык (обычно английский в идентификаторах); в комментариях к неочевидным местам можно пояснить по-русски, если так принято в команде. Подробнее здесь — глава 1, глава 5.
Вопрос. formatOnSave ломает чужие отступы при merge — конфликт каждый раз.
Ответ. Команда должна иметь один форматтер в CI и .editorconfig; тогда diff только по смыслу. Локально отключайте formatOnSave только если конфиг ещё не внедрён — временная мера. Подробнее здесь — глава 1.
Вопрос. Боюсь задавать вопросы в ревью — кажется, что "тупой".
Ответ. Вопрос "рассмотрите…", "что если…" — нормальная часть психологически безопасного ревью. Если не поняли код через полгода — проблема читаемости, а не вашей квалификации. Подробнее здесь — глава 1.
Вопрос. "У меня работает" — а у ревьюера падает тест.
Ответ. Проверьте окружение: версия языка, переменные, порядок тестов, flaky. В PR приложите шаги воспроизведения; культура — когда CI на общем runner зелёный до merge. Подробнее здесь — глава 11.
Вопрос. Начальник просит "на будущее" абстракцию под три несуществующих клиента.
Ответ. Аргументируйте через YAGNI: лишний слой усложняет сопровождение без запроса. Компромисс — простой интерфейс, который легко расширить, когда появится второй реальный кейс. Подробнее здесь — глава 10.
Вопрос. Метод processOrder() делает всё подряд — с чего резать?
Ответ. По ответственностям: валидация, расчёт, сохранение, уведомление — отдельные компоненты или private-методы с говорящими именами. "Вынести в метод" без смены ответственности запутанность не лечит. Подробнее здесь — глава 2.
Вопрос. Модель — только поля и getters/setters, логика в сервисе на 500 строк.
Ответ. Это анемичная модель: доменная логика размазана. Там, где правило устойчиво ("скидка не больше X"), подумайте о методах сущности или value object. Подробнее здесь — глава 6.
Вопрос. Везде catch (Exception e) { } — как поднять тему без конфликта?
Ответ. Покажите пример, где глотание ошибки скрыло инцидент; предложите лог + проброс или узкий catch. Культура — явные сообщения и fail fast, а не "тихий" прод. Подробнее здесь — глава 12.
Вопрос. В коде три разных класса Customer, Client, User про одно и то же.
Ответ. Запах MAPPER: модель кода не совпадает с доменом. Согласуйте термин с аналитиком, постепенно сводите к одному понятию или явному маппингу на границе. Подробнее здесь — глава 5.
Вопрос. Цикломатическая сложность 14 — обязательно делить?
Ответ. Порядка 10 — ориентир для обсуждения, не закон. Если метод читается как рассказ и покрыт тестами — можно оставить; если ревьюер теряется — декомпозиция по смыслу. Подробнее здесь — глава 2.
Вопрос. Ревью висит три дня — это норма?
Ответ. Для потока команды — нет: задержка блокирует интеграцию. Договоритесь о SLA ревью (например, первый ответ в тот же день), уменьшайте размер PR. Подробнее здесь — глава 1.
Вопрос. Спор в ревью: "надо паттерн" vs "надо проще".
Ответ. Критерий — сопровождение через полгода: что проще объяснить новому человеку и безопаснее менять? Паттерн оправдан, если снимает повторяющуюся боль, а не для галочки в резюме. Подробнее здесь — глава 1, справочник.
Вопрос. Старый модуль без форматтера — при правке "причесывать" весь файл?
Ответ. Лучше только затронутые строки, иначе diff на сотни строк скроет суть. Отдельный PR "только форматting" по модулю — если команда решила навести порядок. Подробнее здесь — глава 10.
Вопрос. JSDoc написал, а подсказки в IDE не появились.
Ответ. Проверьте синтаксис docstring, экспорт символа и настройки языка в IDE. Документация публичного API — для тех, кто вызывает модуль извне. Подробнее здесь — глава 1.
Вопрос. Flaky-тест блокирует merge — чинить тест или фичу?
Ответ. Flaky опаснее отсутствия теста: команда перестаёт верить CI. Сначала стабилизируйте тест (время, порядок, моки), потом merge. Подробнее здесь — глава 11.
Вопрос. Вижу техдолг — тикет или чинить "по ходу"?
Ответ. Мелочь на пути задачи — можно сразу; системный долг — тикет с контекстом и оценкой риска, иначе он никогда не попадёт в спринт. Подробнее здесь — глава 10.
Вопрос. Хочу писать "красиво" через LINQ/map, коллеги просят "проще for".
Ответ. Декларативный стиль уместен, когда намерение читается; если команда тонет в цепочках — упростите или добавьте промежуточные имена. Единство важнее личной эстетики. Подробнее здесь — глава 14.
Вопрос. Мутирую объект "для скорости" — когда это плохая идея?
Ответ. Когда объект разделяется между потоками, слоями или тестами — побочные эффекты дают Heisenbugs. Локальная мутация в одном методе часто нормальна; публичные сеттеры "на всё" — повод насторожиться. Подробнее здесь — глава 7.
FAQ — Поисковые запросы
Краткие ответы на формулировки, которые часто вводят в Google и Yandex. Полные разборы — в статьях раздела по ссылкам ниже.
Вопрос. Что такое чистый код (clean code)?
Ответ. Код, который легко читать и менять: понятные имена, простая структура, явные контракты, минимум сюрпризов для коллеги через полгода. Подробнее здесь — культура написания кода.
Вопрос. Что такое цикломатическая сложность и какая норма?
Ответ. Метрика числа независимых путей в функции; рост — сигнал упростить или разбить. Ориентир для повседневного кода — порядка до 10. Подробнее здесь — цикломатическая сложность.
Вопрос. Как правильно называть переменные в Python, Java, C#?
Ответ. Следуйте стилю языка и проекта (snake_case, camelCase, PascalCase); имя отвечает на "что это" и "в каких единицах", не data/temp. Подробнее здесь — именование и стиль.
Вопрос. Чем camelCase отличается от snake_case и PascalCase?
Ответ. camelCase — myVariable (Java, JS); PascalCase — MyClass; snake_case — my_variable (Python, SQL). Главное — единообразие в репозитории. Подробнее здесь — глава 1.
Вопрос. Что такое code review (код-ревью) и зачем оно нужно?
Ответ. Совместная проверка изменений до merge: риски, читаемость, тесты, а не "перепиши как я люблю". Снижает дефекты и распространяет знания. Подробнее здесь — глава 1.
Вопрос. Зачем нужен линтер (ESLint, Pylint, SonarQube)?
Ответ. Автоматически ловит стиль, запахи и частые ошибки, чтобы в ревью не спорить о пробелах. Запускают локально и в CI. Подробнее здесь — глава 1.
Вопрос. Что такое технический долг (tech debt) в коде?
Ответ. Упрощения в прошлом, за которые платите временем и риском при каждой следующей правке. Лечится планом, тестами и малыми PR. Подробнее здесь — YAGNI и техдолг.
Вопрос. Принцип DRY — что значит Don't Repeat Yourself?
Ответ. Не дублировать знание (одно правило в нескольких местах); механическое копирование двух похожих блоков ради читаемости иногда допустимо. Подробнее здесь — глава 1.
Вопрос. SOLID принципы простыми словами для начинающих.
Ответ. Пять правил модульности: одна ответственность, расширение без ломки, подстановка типов, узкие интерфейсы, зависимость от абстракций. Подробнее здесь — глава 1, чек-лист.
Вопрос. Что такое рефакторинг кода и когда его делать?
Ответ. Изменение структуры без смены поведения; безопасно после теста или в маленьких шагах. Отдельно от фичи — в своём PR. Подробнее здесь — глава 10, глава 2.
Вопрос. Как писать комментарии в коде — примеры и правила.
Ответ. Пишите почему и про ограничения (legacy, закон, баг API), а не пересказ цикла. Устаревший комментарий хуже отсутствующего. Подробнее здесь — глава 1.
Вопрос. Что такое магическое число (magic number) в программировании?
Ответ. Число или строка в коде без объяснения смысла (86400, 9999). Заменяйте именованной константой с доменным именем. Подробнее здесь — глава 1, глава 8.
Вопрос. Prettier и ESLint — в чём разница?
Ответ. Prettier — форматирование (отступы, кавычки); ESLint — правила качества и ошибок. Обычно используют оба + CI. Подробнее здесь — глава 1.
Вопрос. Что такое god object и антипаттерн spaghetti code?
Ответ. God object — класс "на всё"; spaghetti — запутанные зависимости. Лечение — декомпозиция по ответственности и явные границы. Подробнее здесь — глобалы и связанность, сложность.
Вопрос. YAGNI — что это и примеры?
Ответ. You Aren't Gonna Need It — не стройте задел "на будущее" без запроса; меньше кода — меньше сопровождения. Подробнее здесь — глава 10.
Вопрос. Как улучшить читаемость кода junior разработчику?
Ответ. Имена вместо комментариев, короткие функции, ранний выход, форматтер, ревью с вопросами, а не приказами. Подробнее здесь — глава 1, справочник симптомов.
Вопрос. Сколько строк кода должно быть в одной функции?
Ответ. Жёсткого лимита нет; ориентир — одна логическая операция и цикломатическая сложность порядка до 10. Длиннее — повод разбить по смыслу. Подробнее здесь — глава 2.
Вопрос. Что такое self-documenting code (самодокументируемый код)?
Ответ. Когда имена и структура объясняют намерение без комментария; не отменяет документирование бизнес-контекста. Подробнее здесь — глава 1.
Вопрос. Почему Singleton считают плохим паттерном?
Ответ. Скрытая глобальная зависимость, сложные тесты, неявный порядок инициализации. Предпочитайте явную инъекцию зависимостей. Подробнее здесь — глава 9.
Вопрос. Value object — что это в доменной модели?
Ответ. Объект-значение без identity (деньги, email, диапазон дат) вместо "голого" string/int. Подробнее здесь — анемичные модели и VO.
Вопрос. Как избежать NullPointerException и проверок на null?
Ответ. Fail fast на входе, явные типы (Optional, nullable-аннотации), контракты API, меньше "тройных" if. Подробнее здесь — null и контракты.
Вопрос. Code smell — что такое "запах кода"?
Ответ. Признак возможной проблемы (длинный метод, дубли, feature envy), а не ошибка сама по себе. Повод для рефакторинга или обсуждения. Подробнее здесь — глава 2, справочник.
Вопрос. EditorConfig — зачем нужен в команде?
Ответ. Единые отступы, кодировка, конец строки во всех IDE; основа вместе с форматтером в репозитории. Подробнее здесь — глава 1.
Вопрос. Как именовать boolean переменные — is, has, can?
Ответ. Префикс is/has/can/should + утверждение: isActive, hasPermission. Избегайте flag, status без смысла. Подробнее здесь — глава 1.
Что запомнить
Раздел собран вокруг простой идеи: код — это средство общения команды во времени. Ниже — сжатые выводы; подробности и примеры — в основной статье и в материале про цикломатическую сложность.
Что такое культура кода
- Договорённости, которые команда реально соблюдает (не PDF в шкафу).
- Инструменты, которые снимают споры о пробелах и стиле (форматтер, линтер, editorconfig).
- Ревью, где обсуждают риски и читаемость, а не "перепиши как я люблю".
Именование и стиль
- Следуйте соглашениям языка и проекта (camelCase, snake_case, PascalCase — не "как нравится").
- Имя отвечает на вопросы — что это, зачем, в каких единицах (
weeklyPayRateRub, неdata). - Короткие имена (
i,j) уместны только при короткой области видимости (типичный цикл на 5–10 строк). - Аббревиатуры — только если они общеприняты в домене (
id,url) или зафиксированы в глоссарии. - Форматирование — зона автоматики; в PR не тратьте время на ручное выравнивание.
Комментарии и документация
- Самодокументируемый код — осмысленные имена и явная структура; не замена бизнес-контексту.
- Комментарий пишут про почему и про ограничения, которые не видны из кода (legacy, регуляторика, баг API).
- Не дублируйте в комментарии то, что уже сказано циклом
forили именем метода. - Устаревший комментарий хуже отсутствующего — обновляйте вместе с кодом в том же PR.
- XML-doc / JSDoc / docstring — для публичного API и подсказок IDE, не для каждой строки.
Сложность и структура
- Цикломатическая сложность — про число независимых путей в функции; рост — сигнал упростить или разбить.
- Ориентир для повседневного кода: держать методы в зоне примерно до 10; выше — осознанное обсуждение в ревью.
- "Вынести в метод" без смены ответственности не лечит запутанность — лечит декомпозиция по смыслу (SRP, политики, данные).
- KISS — проще решение, которое закрывает задачу сейчас; YAGNI — не строить задел "на будущее" без запроса.
- DRY — не копировать знание; дублирование ради читаемости в одном месте иногда допустимо.
MAPPER и модель
- Код описывает часть реальности; лишние классы и примитивы — запах (MAPPER).
- Value object вместо
string/intтам, где в домене есть понятие (статья 6). - Меньше null и if — явные состояния и контракты (статья 8).
- Глобалы и Singleton — скрытая связанность (статья 9).
- Рефакторинг отдельно от фичи в PR (статья 10).
Команда и ревью
- Размер PR 200–400 строк (ориентир) — проще ревью и меньше регрессий.
- В ревью — вопросы и предложения ("рассмотрите…", "что если…"), не ярлыки про человека.
- Психологическая безопасность: ошибки обсуждают как улучшение процесса, не как "вину".
- Метрики (Sonar, complexity) — повод для диалога, не для отчёта "зелёный ради галочки".
Три правила на каждый день
- Перед push — прогон форматтера/линтера и самопроверка по чек-листу.
- В ревью — ищите риск для сопровождения, а не стиль, который уже ловит tooling.
- При сомнении — выберите вариант, который проще объяснить коллеге через полгода.
Дальше: Чек-лист самопроверки — 50 вопросов для закрепления; справочник тем — поиск по симптому.
Куда идти дальше
Полный маршрут — на странице о разделе.