Ответ
Принцип единственной ответственности (Single Responsibility Principle, SRP) — первый принцип SOLID. Он гласит: «Класс должен иметь одну и только одну причину для изменения».
Это означает, что класс должен быть ответственен за одну, чётко определённую часть функциональности. Все его методы должны быть направлены на решение этой единственной задачи.
Проблема — нарушение SRP:
class Order {
// Причина для изменения №1: изменилась бизнес-логика заказа
void calculateTotal() { /* ... */ }
// Причина для изменения №2: изменилась схема базы данных
void saveToDatabase() { /* ... */ }
// Причина для изменения №3: изменился формат печати
void printInvoice() { /* ... */ }
}
// У класса три причины для изменения — это нарушение SRP.
Решение — разделение ответственности:
// Класс отвечает только за данные и логику заказа.
class Order {
void calculateTotal() { /* ... */ }
}
// Класс отвечает только за сохранение/загрузку данных.
class OrderRepository {
void save(Order order) { /* ... */ }
}
// Класс отвечает только за вывод на печать.
class InvoicePrinter {
void print(Order order) { /* ... */ }
}
Преимущества следования SRP:
- Упрощение тестирования: Легче тестировать один аспект поведения.
- Повышение читаемости и поддерживаемости: Классы становятся меньше и понятнее.
- Снижение риска ошибок: Изменения в одной области функциональности не затронут другие.
- Упрощение повторного использования: Класс, делающий одно дело, проще использовать в другом контексте.
Ответ 18+ 🔞
Слушай, а вот этот ваш первый принцип SOLID, SRP, он же просто элементарный, как два пальца об асфальт, блядь!
Представь себе мужика, который одновременно и печку топит, и на скрипке играет, и за свиньями ухаживает. Ну и какого хуя? Он же везде накосячит, этот распиздяй! Так и в коде — если класс пытается делать всё на свете, это пиздец, а не архитектура.
Вот смотри, классический пример говнокода, где всё свалено в одну кучу:
class Order {
void calculateTotal() { /* ... */ }
void saveToDatabase() { /* ... */ }
void printInvoice() { /* ... */ }
}
Этот ваш Order — он же, сука, и бухгалтер, и грузчик, и печатник в одном флаконе! Захотелось поменять принтер — трогай класс заказа. Решили в базу новое поле добавить — опять лезь в этот же класс. Это ж какая-то ебля на постном масле, а не разработка!
А теперь правильный подход, где каждый занимается своим делом, как в хорошей артели:
class Order {
void calculateTotal() { /* ... */ }
}
class OrderRepository {
void save(Order order) { /* ... */ }
}
class InvoicePrinter {
void print(Order order) { /* ... */ }
}
Вот видишь? Один — деньги считает, второй — в базу тыкает, третий — бумажки печатает. Красота, ёпта! Каждый как хитрая жопа — знает свой шесток.
И плюсов-то — овердохуища:
- Тестировать — раз плюнуть. Подсунул заглушку репозиторию и проверяй логику заказа. Никаких танцев с бубном.
- Читать и менять — вообще сказка. Не надо рыться в трёхэтажном методе, где всё перемешано.
- Ошибки — они теперь локализованы, как проказа в карантине. Сломался принтер — чини принтер, а не весь заказ целиком.
- Переиспользовать — да запросто! Захотел считать итоги в мобильном приложении — бери класс
Orderи тащи его, он же про базы и принтеры нихуя не знает.
В общем, принцип-то простой, как хуй с горы: делай одну вещь, но делай её хорошо, блядь. Не распыляйся, не будь тем самым мудаком-универсалом, который везде успевает и везде косячит.