В этом приложении собран список коротких рекомендаций для поиска и исправления проблем с кодом.
Рекомендации основаны на тезисах и доводах из предыдущих глав. Перед применением стоит прочесть текст самих глав, чтобы оценить, насколько эти приёмы подходят вашему проекту, стилю и привычкам в написании кода.
Это не список правил, которым надо неукоснительно следовать. Это скорее набор советов, которые можно принять к сведению. Используйте их осознанно.
- Ищите запахи кода в проекте.
- Обращайте внимание на ощущения типа «тяжело читать, менять, тестировать, держать в голове».
- Определите границы изменений и наметьте «швы».
- Покройте выбранную часть кода тестами.
- Опишите тестами как можно больше эдж-кейсов.
- Настройте автоматический запуск тестов и линтинг кода.
- Переведите предупреждения компилятора и линтера в разряд ошибок.
- Используйте маленькие шаги и атомарные коммиты.
- Создавайте компактные, но подробные пул-реквесты.
- Применяйте одну технику рефакторинга за раз.
- Чините баги и добавляйте фичи отдельно от рефакторинга.
- Соблюдайте приоритет преобразований.
- Не смешивайте рефакторинг тестов и кода приложения.
- Применяйте инструменты автоматизированного рефакторинга в IDE.
- Используйте диффы изменений для поиска ошибок.
- Проверяйте все изменение кода тестами, даже самые маленькие.
- Внедрите автоматическое форматирование кода.
- Проверьте код линтером и статическими анализаторами.
- Замените «костыли» фичами языка и окружения.
- Проясните непонятные имена.
- Расшифруйте незадокументированные аббревиатуры.
- Декомпозируйте сущности с длинными именами.
- Используйте разные имена для разных сущностей.
- Внедрите повсеместный язык.
- Исправьте врущие имена.
- Отделите явное дублирование от недостатка информации о системе.
- Проводите регулярные аудиты дублированного кода.
- Выносите повторяющиеся данные в переменные.
- Выносите повторяющиеся действия в функции.
- Описывайте намерение в названиях функций.
- Структурируйте код так, чтобы выдавать информацию читателю дозировано.
- Помните об ограничении рабочей памяти мозга, следите за количеством сущностей в функции.
- Упорядочьте информацию и используемые термины по уровням абстракции.
- Декомпозируйте задачи на основе данных, которые в них используются.
- Проверяйте, чтобы у функции была только одна причина для изменения.
- Следите, чтобы модуль самостоятельно обеспечивал валидность своих данных.
- Выделяйте состояния, через которые проходят данные приложения.
- Сделайте передачу невалидных данных в коде затруднительной.
- Валидируйте данные перед использованием.
- Используйте селекторы для «подготовки» данных под разные условия использования.
- Установите лимит на цикломатическую и когнитивную сложность кода.
- «Выпрямите» условия:
- Используйте ранний возврат;
- Применяйте законы де Моргана;
- Используйте предикаты для динамических условий;
- Используйте паттерны проектирования (Стратегия, Null-объект);
- Применяйте паттерн-матчинг там, где возможно.
- Чаще используйте чистые функции.
- Стремитесь к ссылочной прозрачности для более простой отладки.
- Воспринимайте данные и код по умолчанию как неизменяемые.
- Отодвиньте сайд-эффекты к краям модуля / функции / юзкейса.
- Проверяйте простоту кода тестами: чем проще писать тесты, тем проще код.
- Пишите адаптеры, чтобы уменьшить зацепление и создавать меньше моков в тестах.
- Разделяйте эффекты на команды и запросы.
- Выявляйте нарушения CQS по сигнатурам и именам функций.
- Используйте разные модели для чтения и записи данных, когда это уместно.
- Выделяйте разные виды ошибок в приложении.
- Обрабатывайте ошибки централизованно.
- Переходите к обработке ошибок как можно раньше.
- Старайтесь отобразить возможные ошибки в сигнатуре функции.
- Проверяйте входные данные перед началом работы с ними.
- Используйте логирование и аналитику в обработчиках последней надежды.
- Используйте декораторы для cross-cutting concerns.
- Держите зацепление низким, а связность высокой.
- Проверяйте связность по входным, выходным данным и зависимостям кода.
- Обозначьте гарантии модулей через их публичное API.
- Сделайте общение модулей менее зацепленным:
- Используйте сообщения / события;
- Применяйте паттерны (Наблюдатель).
- Ограничивайте количество зависимостей модуля.
- Компонуйте преобразования данных, а не сайд-эффекты.
- Отделяйте логику от сайд-эффектов.
- Отделяйте данные от поведения.
- Не торопитесь обобщать.
- Компонуйте сложные типы из простых вместо наследования.
- Используйте дженерики, когда уверены, что структура типа не поменяется.
- Обращайте внимание на условия, они могут указать на нарушение принципа подстановки.
- Используйте повсеместный язык для моделирования домена.
- Отражайте этапы жизненного цикла данных приложения в их состояниях.
- Старайтесь не зависеть напрямую от стороннего кода.
- Добавляйте анти-коррозионный слой там, где может поменяться формат данных или API.
- Разделяйте UI-логику и бизнес-логику.
- Отделяйте конфигурацию от кода.
- Используйте типы для описания предметной области.
- Сделайте невалидные состояния данных «невыразимыми» в типах.
- Выявляйте нарушения CQS по сигнатурам методов и функций.
- Применяйте технику «вычёркивания», чтобы определить информационную насыщенность сигнатур.
- Рефакторьте тестовый код и код приложения по очереди.
- Используйте больше простых стабов и тестовых данных, чем сложных моков.
- Избавляйтесь от тестов-дубликатов и никогда-не-падающих тестов.
- Избавьтесь от конфликтов между кодом и тем, что «рядом с ним».
- Уточните расплывчатые комментарии: добавьте контекста, примеров и причин именно такой реализации.
- Проводите регулярные аудиты комментариев, документации и задач в трекере.
- Оцените ресурсы, выгоды и риски при выборе между рефакторингом и переписыванием с нуля.
- Используйте мета-информацию о проекте из системы контроля версий для анализа состояния проекта.
- Используйте технику «Рядом, а не вместо» при рефакторинге больших кусков кода.
- Уделяйте время рефакторингу регулярно.
- Помните о правиле бойскаута.
- Опирайтесь на измеримые метрики при оценке улучшений.