В чем суть принципа единственной ответственности (Single Responsibility Principle, SRP)?

«В чем суть принципа единственной ответственности (Single Responsibility Principle, SRP)?» — вопрос из категории Паттерны, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Принцип единственной ответственности (SRP) — это первый принцип SOLID. Он гласит: «Класс должен иметь одну и только одну причину для изменения».

Простыми словами: Модуль (класс, структура, функция) должен быть ответственен за одну конкретную задачу или функциональность. Если у модуля несколько несвязанных обязанностей, изменения в одной из них могут неожиданно сломать другие.

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

// Класс нарушает SRP, так как отвечает и за данные пользователя, и за логику email, и за сохранение.
class UserHandler {
    var name: String
    var email: String

    init(name: String, email: String) {
        self.name = name
        self.email = email
    }

    func saveToDatabase() {
        // Код для сохранения в БД
    }

    func sendWelcomeEmail() {
        // Код для отправки email
    }
}

Пример соблюдения SRP (рефакторинг):

// 1. Класс только для данных
struct User {
    let name: String
    let email: String
}

// 2. Класс только для работы с хранилищем
class UserRepository {
    func save(_ user: User) {
        // Код для сохранения в БД
    }
}

// 3. Класс только для email-рассылок
class EmailService {
    func sendWelcomeEmail(to user: User) {
        // Код для отправки email
    }
}

// Использование
let user = User(name: "Петр", email: "peter@example.com")
let repository = UserRepository()
let emailService = EmailService()

repository.save(user)
emailService.sendWelcomeEmail(to: user)

Преимущества следования SRP:

  • Упрощение тестирования: Легче протестировать изолированный модуль с одной ответственностью.
  • Повышение читаемости: Код становится понятнее, так как каждый класс имеет четкое назначение.
  • Снижение связанности: Изменения в логике отправки email не затронут код сохранения данных и наоборот.
  • Упрощение повторного использования: Класс EmailService можно использовать для отправки любых email, а не только приветственных.

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