Ответ
Принцип единственной ответственности (SRP) — это первый принцип SOLID. Он гласит: «У класса должна быть только одна причина для изменения». На практике это означает, что класс должен решать одну конкретную задачу или отвечать за одну область ответственности.
Проблемный пример (нарушение SRP):
Класс Order занимается и бизнес-логикой заказа, и его сохранением в БД, и отправкой уведомлений.
class Order {
public function calculateTotal() { /* ... */ }
public function saveToDatabase() { /* ... */ }
public function sendConfirmationEmail() { /* ... */ }
// При изменении правил расчёта, схемы БД или формата email
// придётся менять один и тот же класс.
}
Решение (соблюдение SRP): Разделяем ответственности на отдельные классы.
class Order {
public function calculateTotal() { /* ... */ }
// Отвечает только за данные и логику заказа.
}
class OrderRepository {
public function save(Order $order) { /* ... */ }
// Отвечает только за персистентность (работу с БД).
}
class NotificationService {
public function sendOrderConfirmation(Order $order) { /* ... */ }
// Отвечает только за отправку уведомлений.
}
Теперь, если изменится способ отправки email (например, добавится SMS), мы будем править только NotificationService. Изменение структуры таблицы в БД затронет только OrderRepository.
Преимущества следования SRP:
- Упрощение тестирования: Легко протестировать
OrderRepositoryотдельно от логики отправки писем. - Повышение читаемости и поддерживаемости: Классы становятся меньше и понятнее.
- Снижение связанности: Изменения в одной части системы с меньшей вероятностью сломают другую.
- Упрощение повторного использования: Класс
NotificationServiceможно использовать для отправки уведомлений не только о заказах.
Ответ 18+ 🔞
Давай разберём этот принцип, а то он звучит как какая-то мантра из йоги, а на деле всё проще простого.
Представь себе чувака, который в жизни делает всё сам. Он и пельмени лепит, и машину чинит, и квартиру убирает, и отчёт начальнику пишет. Со стороны — молодец, универсальный солдат. А на деле? Как только начальник захочет отчёты в другом формате, наш герой весь свой график по уши, потому что ему теперь и пельмени недолепленные, и машина с незакрученной гайкой, и в квартире бардак. Одна причина для изменения (новый формат отчёта) — а последствия ебать на всю его деятельность. Вот это и есть нарушение SRP в жизни.
Так же и с классами. Если твой класс делает три разных дела, то любое изменение в одном из них заставляет тебя ковыряться во всём этом монстре. Доверия ебать ноль к такому коду, потому что поправил одно — сломал два других.
Смотри на примере, который ты привёл. Класс Order — это же пиздопроебина полная! Он и деньги считает, и в базу пишет, и письма рассылает. Представь, что тебе нужно поменять провайдера для отправки email (скажем, с Mailgun на SendGrid). Ты лезешь в класс заказа, рискуя сломать логику расчёта или, того хуже, запись в базу. Хуй с горы, а не архитектура.
А теперь правильный подход, где каждый класс — хитрая жопа, которая умеет делать только одно, но делает это хорошо.
Order— тупо данные заказа и логика их обработки (посчитать итог, применить скидку). Его дело — бизнес-правила.OrderRepository— его единственная страсть — впендюрить данные в базу и достать их оттуда. Схема БД поменялась? Правим только его, и всем да похуй.NotificationService— манда с ушами, которая знает, как и куда слать уведомления. Захотел добавить SMS или Telegram? Изменяешь только этот сервис, не трогая ни заказы, ни базу.
В чём профит, спросишь?
- Тестирование — ебушки-воробушки. Хочешь проверить, правильно ли сохраняется заказ? Тестируешь
OrderRepositoryв изоляции, подсовывая ему фейковую базу. Не нужно городить огород с моками для отправки писем. - Читаемость. Открыл класс — и сразу понятно, за что он отвечает. Не нужно полчаса вникать, где тут заканчивается расчёт НДС и начинается коннект к SMTP-серверу.
- Меньше связанности. Классы общаются через чёткие интерфейсы.
NotificationServiceвообще не знает, что такое база данных. Он получил объект заказа — отправил письмо. Всё. Если он сломается, то сломается только отправка писем, а не весь процесс оформления заказа. - Переиспользование. Этот самый
NotificationServiceможно взять и прикрутить к системе отзывов или оповещений о доставке. Потому что он не завязан на логику заказов, он просто умеет слать сообщения.
Короче, смысл в том, чтобы не создавать полупидоров, которые за всё в ответе, но ничего толком не умеют. Лучше сделать несколько узких специалистов, каждый из которых — мастер в своём деле. Тогда и жить проще, и код не превращается в ядерную вошь, которую страшно трогать.