78 lines
5.4 KiB
Markdown
78 lines
5.4 KiB
Markdown
---
|
||
aliases:
|
||
- SRP
|
||
- принцип единственной ответственности
|
||
- Single Responsibility
|
||
tags:
|
||
- maturity/🌱
|
||
date: 2024-09-27
|
||
---
|
||
Каждый класс или метод должен иметь **только одну причину для изменения**, то есть решать одну задачу. Этот принцип называется **Принципом единственной ответственности (SRP)** и входит в набор [[SOLID]]-принципов, которые помогают создавать качественный и поддерживаемый код.
|
||
|
||
> [!EXAMPLE] Причина для изменения
|
||
> Под "причиной для изменения" подразумевается аспект функциональности, который может измениться из-за изменения бизнес-требований. Например, класс, управляющий пользователями, должен модифицироваться только при изменении требований к управлению пользователями, но не из-за обновлений в логике отправки уведомлений.
|
||
|
||
Классы или методы, выполняющие несколько задач, усложняют их поддержку. Любое изменение может неожиданно затронуть другие области, увеличивая вероятность ошибок и сложность тестирования.
|
||
|
||
Каждый класс или метод должен иметь **только одну** причину для изменения, то есть решать лишь одну задачу.
|
||
|
||
Преимущества:
|
||
1. **Упрощенная поддержка:** Изменения в одной части системы не влияют на другие, снижая риск побочных эффектов.
|
||
2. **Повышенная переиспользуемость:** Узкоспециализированные классы можно легко применять повторно. Например, класс `EmailService` можно использовать в разных модулях для отправки уведомлений без доработок.
|
||
3. **Улучшенная читаемость:** Четко определенные обязанности классов упрощают понимание кода для текущих и будущих разработчиков.
|
||
4. **Снижение риска ошибок:** Разделение ответственности на изолированные компоненты помогает уменьшить вероятность ошибок, так как изменения в одной области не затрагивают другую.
|
||
5. **Упрощение тестирования:** Можно протестировать независимо каждый компонент.
|
||
|
||
## Пример нарушения SRP
|
||
Рассмотрим класс, который одновременно управляет данными пользователя и отправляет сообщения по электронной почте:
|
||
|
||
```java
|
||
public class UserManager {
|
||
private String userData;
|
||
|
||
public void updateUser(String data) {
|
||
// Логика управления пользователем
|
||
this.userData = data;
|
||
}
|
||
|
||
public void sendEmail(String email, String message) {
|
||
// Логика отправки сообщений
|
||
System.out.println("Sending email to: " + email);
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
Класс `UserManager` выполняет две разные задачи: управление данными пользователя и отправку уведомлений. ==Это нарушает принцип единственной ответственности, так как задачи имеют разные причины для изменения.== Такой подход увеличивает связанность кода, усложняет его поддержку и повышает риск ошибок.
|
||
|
||
Разделите обязанности на отдельные классы:
|
||
|
||
```java
|
||
public class UserService {
|
||
public void updateUser(String data) {
|
||
// Логика управления пользователем
|
||
}
|
||
}
|
||
|
||
public class EmailService {
|
||
public void sendEmail(String email, String message) {
|
||
// Логика отправки сообщений
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
Теперь каждое изменение будет затрагивать только соответствующий класс. Это улучшает читаемость, тестируемость и устойчивость к изменениям.
|
||
***
|
||
## Мета информация
|
||
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
|
||
**Родитель**:: [[SOLID]]
|
||
**Источник**::
|
||
**Создана**:: [[2024-09-27]]
|
||
**Автор**::
|
||
### Дополнительные материалы
|
||
-
|
||
|
||
### Дочерние заметки
|
||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|