Что такое принцип единственной ответственности (SRP, Single Responsibility Principle) в ООП

Ответ

Принцип единственной ответственности (SRP) гласит, что класс должен иметь только одну причину для изменения, т.е. выполнять лишь одну задачу. Это упрощает поддержку кода, уменьшает связность и облегчает тестирование.

Пример нарушения SRP:

class User {
    fun saveToDb(user: User) { /*...*/ }
    fun sendEmail(user: User) { /*...*/ }
}

Правильный вариант:

class UserRepository {
    fun saveToDb(user: User) { /*...*/ }
}

class EmailService {
    fun sendEmail(user: User) { /*...*/ }
}

Ключевые преимущества:

  • Изменение логики работы с БД не затрагивает отправку email
  • Каждый класс проще тестировать изолированно
  • Код становится более читаемым и понятным

Ответ 18+ 🔞

Да ты посмотри на эту дичь! Принцип единственной ответственности, говоришь? Ну это когда один класс — одна задача, и всё тут. Представь себе мужика, который и плитку кладёт, и сантехнику ставит, и проводку делает. Вроде мастер на все руки, а в итоге унитаз в стене замуровывает, потому что руки-крюки от такой ебанутости. Так и в коде — если класс делает всё подряд, он превращается в вот такого вот «универсала», с которым потом овердохуища проблем.

Вот смотри, какой пиздец бывает, когда его нарушают:

class User {
    fun saveToDb(user: User) { /*...*/ } // Сохраняет в базу
    fun sendEmail(user: User) { /*...*/ } // А тут уже письма шлёт!
}

Чувак, ты веришь? Один класс и в БД пихает, и по почте рассылает. Это ж чистой воды распиздяйство! Сегодня захотели поменять библиотеку для отправки писем — придётся лезть в класс User и там всё перепиливать. Завтра схема в базе поменялась — опять в этот же класс. Волнение ебать — одно изменение в одном месте потянет за собой кучу ненужного риска. Доверия ебать ноль к такому коду.

А теперь правильный подход, где у каждого своя работа:

class UserRepository { // Этот чувак отвечает ТОЛЬКО за базу
    fun saveToDb(user: User) { /*...*/ }
}

class EmailService { // А этот — ТОЛЬКО за письма
    fun sendEmail(user: User) { /*...*/ }
}

Видишь разницу? Ёперный театр, да это же просто небо и земля!

Ключевые плюсы, ради которых стоит не лениться:

  • Изменение логики работы с БД не затрагивает отправку email. Захотел поменять базу с MySQL на PostgreSQL? Иди к UserRepository и там колдуй. EmailService даже не узнает об этом, ему да похуй. Никаких сюрпризов.
  • Каждый класс проще тестировать изолированно. Тестируешь репозиторий — подменяешь базу заглушкой. Тестируешь сервис писем — подменяешь почтовый клиент. Никакой манды с ушами, где всё связано в один большой ком.
  • Код становится более читаемым и понятным. Открываешь класс и сразу видно — а, это хранилище, оно только сохраняет. А это рассыльщик, он только шлёт. Никаких хитрых жоп, которые делают тебе сюрприз на ровном месте.

В общем, суть в чём: не делай из своего класса пидараса шерстяного, который пытается быть всем для всех. Пусть каждый занимается своим делом, и в проекте будет порядок, а не пиздопроебибна.

Видео-ответы