Ответ
Нарушением Принципа единственной ответственности (Single Responsibility Principle, SRP) является ситуация, когда класс или метод отвечает за несколько несвязанных или слабосвязанных задач. Такой класс имеет "слишком много причин для изменения".
Антипаттерн: "Божественный объект" (God Object)
// НАРУШЕНИЕ SRP: Класс делает слишком много.
class UserManager {
// Ответственность 1: Работа с данными (Persistence)
public void saveToDatabase(User user) { /* ... */ }
public User loadFromDatabase(Long id) { /* ... */ }
// Ответственность 2: Бизнес-логика валидации
public boolean validateEmail(String email) { /* ... */ }
public boolean validatePassword(String password) { /* ... */ }
// Ответственность 3: Отправка уведомлений (Communication)
public void sendWelcomeEmail(User user) { /* ... */ }
public void sendPasswordResetEmail(User user) { /* ... */ }
// Ответственность 4: Генерация отчетов (Reporting)
public PdfDocument generateUserReport(User user) { /* ... */ }
}
Проблемы такого дизайна:
- Сложность тестирования: Чтобы протестировать валидацию, нужно учитывать побочные эффекты от БД или email.
- Хрупкость: Изменение формата email или логики генерации отчета затронет один монолитный класс.
- Низкая переиспользуемость: Нельзя использовать логику валидации отдельно от отправки email.
- Сложность понимания: Класс становится слишком большим и запутанным.
Решение (Рефакторинг по SRP):
// Каждый класс имеет одну четкую ответственность.
class UserRepository { // Работа с хранилищем
void save(User user) { /* ... */ }
User findById(Long id) { /* ... */ }
}
class UserValidator { // Валидация бизнес-правил
boolean isValid(User user) { /* ... */ }
}
class EmailService { // Отправка сообщений
void sendWelcome(User user) { /* ... */ }
}
class ReportGenerator { // Создание отчетов
PdfDocument generateForUser(User user) { /* ... */ }
}
// Координирующий сервис (может использовать все вышеперечисленное)
class UserRegistrationService {
private UserRepository repository;
private UserValidator validator;
private EmailService emailService;
// ...
public void register(User user) {
if (validator.isValid(user)) {
repository.save(user);
emailService.sendWelcome(user);
}
}
}
Теперь каждый класс меняется только по одной причине, его легче тестировать, поддерживать и повторно использовать.