DRY (Don’t Repeat Yourself, не повторяйся), также известен как DIE (Duplication Is Evil, дублирование это зло).
Этот принцип заключается в том, что нужно избегать повторений одного и того же кода. Лучше использовать универсальные свойства и функции.
Как обнаружить проблему:
- Изменяя алгоритм или поведение, приходится менять код в нескольких местах
- В проекте есть одинаковые части кода
Как исправить проблему:
- Просканировать код средствами статического поиска дублирующего кода
- Подобрать нужную абстракцию для дублируемого кода
- Заменить весь дублирующий код на выбранную абстракцию
KISS (Keep It Simple, Stupid, не усложняй).
Смысл этого принципа программирования заключается в том, что стоит делать максимально простую и понятную архитектуру, применять шаблоны проектирования и не изобретать велосипед.
Как обнаружить проблему:
- Если только что написанный код невозможно прочитать, бегло пробежав глазами, приходится останавливаться
- Если блок кода содержит больше 50 строк
- Если код необходимо пояснять комментариями
Как исправить проблему:
- Код разбить на небольшие короткие блоки кода, которые выполняют одно простое действие
- Сложный код разбить на группу простых методов/функций
- Провести рефакторинг наименования, дать говорящие названия (методы и функции должны говорить, что они делают и в каком контексте, переменные должны иметь понятные читаемы названия и не требовать комментариев)
YAGNI (You Ain’t Gonna Need It, вам это не понадобится).
Смысл принципа в том, чтобы реализовать только поставленные задачи и отказаться от избыточного функционала. При выборе того или иного решения нужно исходить из оценки эффективности разработки и сопровождения: если цена сопровождения увеличивается значительно при сокращении цены разработки или цена разработки превышает договорную, даже с учетом значительного сокращения цены сопровождения - это точно неправильное решение. Любое решение должно уменьшать стоимость разработки и сопровождения, в противном случае не должно применяться.
Как обнаружить проблему:
- Во время реализации приходится разрабатывать код, который напрямую не решает поставленную задачу
Как исправить проблему:
- Использовать подход TDD (Test-Driven Development)
Принцип SOLID в упрощенном варианте означает, что когда при написании кода используется несколько принципов вместе, то это значительно облегчает дальнейшую поддержку и развитие программы.
Single responsibility principle (принцип единственной обязанности) — на каждый класс должна быть возложена одна-единственная обязанность.
Как обнаружить проблему:
- Если код выполняет несколько действий над сущностями
- Если код выполняет действия над несколькими сущностями
- Если код выполняет действие в нескольких контекстах
- В коде присутствуют анти-паттерн проектирования: GodObject
- В коде есть классы, имена которых содержат следующие названия: Manager, Super, Common
- В имени классов есть слова And и/или Or
- Требуется описания, что делает класс
Как исправить проблему:
- Провести декомпозицию по принципу DDD (Domain-driven design): разделить все на объекты, действия и контексты
- Создать классы для получившегося разделения.
Open/closed principle (принцип открытости/закрытости) — программные сущности должны быть закрыты для изменения но открыты для расширения.
Как обнаружить проблему:
- При написании новой бизнес-логики, требуется менять уже существующую
- Добавление новой функциональности становится все дороже и дороже — повышается complexity
- Метод, функция или класс меняет свое поведение в зависимости от входных параметров
Как исправить проблему:
- Ввести абстракцию
Liskov substitution principle (принцип подстановки Барбары Лисков) — функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом. Подклассы не могут замещать поведения базовых классов. Подтипы должны дополнять базовые типы.
Как обнаружить проблему:
- Код перестает работать ожидаемо, если вместо объекта в качестве аргумента отправить объект наследник
Как исправить проблему:
- Использовать на практике контрактное проектирование
Interface segregation principle (принцип разделения интерфейса) — много специализированных интерфейсов лучше, чем один универсальный.
Как обнаружить проблему:
- В коде присутствуют методы заглушки с return null или throw Exception
- При реализации класса по интерфейсу необходимо создавать методы, которые в классе совершенно не нужны
- Очень большой список методов в интерфейсе
Как исправить проблему:
- Определить ответственность и разделить один интерфейс на несколько
- Использовать подход TDD (Test-Driven Development)
- Не использовать методы заглушки
- Dependency inversion principle (принцип инверсии зависимостей) — зависимости внутри системы строятся на основе абстракций. Модули верхнего уровня не зависят от модулей нижнего уровня. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Как обнаружить проблему:
- Сложно тестировать код
- Высокая связанность классов: при переносе куска кода в новый проект, он тянет за собой много ненужных сущностей
Как исправить проблему:
- Использовать подход TDD (Test-Driven Development)
- Для всех ключевых сущностей сперва сделать абстракцию и работать с ней, а не с реализацией