S — единственная ответственность
Single Responsibility Principle (SRP) — у класса должна быть ровно одна причина для изменения. Не «один метод» и не «маленький класс» — а одна зона ответственности.
// ❌ плохо: один класс делает три разных дела
class Order {
void calculateTotal() { ... } // бизнес-логика
void saveToDatabase() { ... } // работа с БД
void sendConfirmationEmail() { ... } // отправка писем
}
// ✅ хорошо: каждая ответственность — свой класс
class Order { void calculateTotal() { ... } }
class OrderRepository { void save(Order order) { ... } }
class OrderNotifier { void sendConfirmation(Order order) { ... } }
Если поменяется логика расчёта суммы — менять только Order. Если поменяется способ хранения (с БД на файл) — только OrderRepository. Изменение одной причины не задевает остальное.
Копнуть глубже
Как распознать нарушение SRP на практике. Спроси себя: «по каким причинам этот класс может поменяться?» Если ответов несколько и они никак не связаны (например, “поменяется формат письма” и “поменяется алгоритм скидки”) — это явный сигнал разбить класс.
Зачем это вообще нужно:
- Меньше риска при изменениях. Поправил отправку писем — не боишься сломать расчёт суммы, это разные классы.
- Проще тестировать. Маленький класс с одной обязанностью тестируется в разы проще, чем “божественный класс” (God Object), который делает всё сразу.
- Проще переиспользовать.
OrderRepositoryможно использовать где угодно, не таща за собой логику отправки писем.
SRP — не «один метод на класс». Класс Order с десятком методов про расчёт суммы — это всё ещё одна ответственность (“считать стоимость заказа”), и это нормально. Дробить ради дробления не нужно.
• как распознать нарушение SRP и почему это не значит "один метод на класс" (если дошёл до 2-го слоя).