Первым и самым важным шагом является правильная идентификация дублирования. DRY борется не с дублированием кода как текста, а с дублированием знания и поведения. Два одинаковых фрагмента кода в разных модулях, которые изменяются по разным причинам и в разное время, — это не нарушение DRY, а случайное совпадение. Их объединение создаст нежелательную связь (coupling). Истинное нарушение DRY — это когда одно и то же правило, алгоритм или политика бизнес-логики записаны в нескольких местах. Изменение этого правила в будущем потребует внесения правок во все эти места, что чревато ошибками. Поэтому перед рефакторингом всегда задавайте вопрос: «Представляет ли этот код одно и то же знание? Изменится ли он по одной и той же причине?».
Чеклист по применению DRY на разных уровнях архитектуры:
- Уровень функций и методов. Это самый простой уровень. Чеклист:
* Если да, создайте приватный/публичный метод с четким, отражающим суть операции именем.
* Параметризуйте метод, чтобы он покрывал небольшие вариации, но избегайте передачи флагов (boolean flags), которые радикально меняют поведение метода — это часто признак нарушения SRP (Single Responsibility Principle).
- Уровень классов и модулей. Здесь DRY тесно переплетается с принципами единственной ответственности (SRP) и открытости/закрытости (OCP). Чеклист:
* Используйте шаблоны проектирования: Стратегия (Strategy) для interchangeable алгоритмов, Шаблонный метод (Template Method) для скелета алгоритма с вариативными шагами, Декоратор (Decorator) для добавления поведения.
- Уровень данных и конфигурации. Дублирование данных — часто упускаемый из виду аспект. Чеклист:
* Следите за дублированием схем данных (например, одинаковые DTO-объекты на стороне клиента и сервера). Рассмотрите генерацию кода из единого источника истины (OpenAPI/Swagger спецификация для API, protobuf-схемы).
- Уровень инфраструктуры и развертывания (Infrastructure as Code). Современный DevOps немыслим без DRY. Чеклист:
* В Docker создавайте базовые образы (base images) для однотипных сервисов, чтобы избежать дублирования инструкций `RUN apt-get install...` в каждом Dockerfile.
* В CI/CD пайплайнах (GitLab CI, GitHub Actions) выносите повторяющиеся шаги в отдельные job templates или reusable workflows.
- Уровень документации и тестов. Знание живет не только в коде. Чеклист:
* Следите, чтобы описание бизнес-правил не расходилось с их реализацией в коде. Рассмотрите подход Specification by Example или BDD-фреймворки (Cucumber), где тест-кейсы сами являются исполняемой документацией.
Предупреждения и антипаттерны. Слепое следование DRY может навредить. Избегайте:
* Преждевременного обобщения (Premature Generalization). Не выносите код «на вырост», если дублирования еще нет или оно гипотетическое.
* Создания хрупких абстракций, которые связаны не общим смыслом, а лишь синтаксическим сходством. Это приводит к высокому зацеплению (coupling).
* Нарушения принципа близости: не выносите в общую библиотеку код, который используется только одним проектом, просто потому что «так чище».
Настройка DRY — это непрерывный процесс рефакторинга, а не разовое действие. Интегрируйте проверки на дублирование в ваш workflow: используйте статические анализаторы кода (SonarQube, CodeClimate), проводите регулярные ревью кода с фокусом на поиск общего знания. Помните, что конечная цель DRY — не минимизация строк кода, а максимизация поддерживаемости, уменьшение энтропии системы и создание кодовой базы, где каждая часть знания имеет единственное, непротиворечивое и авторитетное представление.
Комментарии (15)