Ответ
SRP (Single Responsibility Principle) — это первый принцип SOLID, который гласит: «Класс должен иметь одну и только одну причину для изменения». Это означает, что класс должен быть ответственен за одну, четко определенную часть функциональности.
Суть принципа: Высокая связность (cohesion) внутри класса и низкая связанность (coupling) между классами. Изменение в бизнес-логике не должно влиять на код, отвечающий за сохранение данных, и наоборот.
Пример нарушения SRP:
// Класс нарушает SRP, так как совмещает три разные ответственности:
// 1. Представление данных книги.
// 2. Логика сохранения в БД.
// 3. Логика форматирования для печати.
class Book {
private String title;
private String author;
// Конструкторы, геттеры, сеттеры...
public void saveToDatabase() {
// Логика подключения к БД и INSERT/UPDATE
System.out.println("Saving book to database...");
}
public void printToConsole() {
// Логика форматирования вывода
System.out.println("Book: " + title + " by " + author);
}
}
Проблемы такого подхода:
- Если изменится способ сохранения (переход с JDBC на JPA), придется менять класс
Book. - Если изменится формат вывода (HTML вместо консоли), снова меняется
Book. - Класс сложно тестировать из-за смешения логики.
Рефакторинг с соблюдением SRP:
// Класс Book отвечает ТОЛЬКО за хранение данных о книге.
class Book {
private String title;
private String author;
// Только данные и, возможно, валидация этих данных.
}
// Класс BookRepository отвечает ТОЛЬКО за персистентность (сохранение/загрузку).
class BookRepository {
public void save(Book book) {
// Вся логика работы с базой данных здесь
System.out.println("Saving book to database...");
}
}
// Класс BookPrinter отвечает ТОЛЬКО за представление книги.
class BookPrinter {
public void printToConsole(Book book) {
System.out.println("Book: " + book.getTitle() + " by " + book.getAuthor());
}
public String printToHtml(Book book) { /* ... */ }
}
Практические выгоды от следования SRP:
- Упрощение тестирования: Каждый класс тестируется изолированно.
BookRepositoryможно протестировать с mock-базой, аBookPrinter— без нее. - Повышение читаемости и поддерживаемости: Легче понять, за что отвечает каждый класс.
- Снижение риска побочных эффектов: Изменение в логике печати не затронет код сохранения в БД.
- Упрощение повторного использования: Класс
Bookтеперь можно использовать в любом контексте, не таская за собой зависимости от базы данных или UI.
Важное уточнение: «Ответственность» — это не «один метод», а одна ось изменения (reason to change). В реальности класс может содержать несколько методов, если они относятся к одной зоне ответственности (например, класс Validator с методами validateEmail, validatePhone).