Struchkov Mark
741a924908
All checks were successful
continuous-integration/drone/push Build is passing
106 lines
9.8 KiB
Markdown
106 lines
9.8 KiB
Markdown
---
|
||
aliases:
|
||
- Cohesion
|
||
- связности
|
||
- связность
|
||
tags:
|
||
- maturity/🌱
|
||
date: 2024-11-24
|
||
---
|
||
Связность (cohesion) — это мера того, насколько функции внутри одного модуля связаны друг с другом и работают вместе для выполнения конкретной задачи. Высокая связность означает, что модуль фокусируется на одной задаче и все его компоненты направлены на достижение этой цели. Например, модуль обработки платежей включает только функции, связанные с платежами, что делает его логически целостным.;
|
||
|
||
Примеры применения
|
||
- [[../../../../wiki/zero/00 Микросервисная архитектура|Микросервисная архитектура]]. Сервис с высокой связностью сосредоточен на конкретной бизнес-задаче, например, управлении пользователями или платежами. Это позволяет эффективно выполнять свою функцию и поддерживать независимость сервиса. Например, сервис управления пользователями может добавлять, обновлять и удалять пользователей без взаимодействия с другими сервисами, что делает его легким в поддержке.
|
||
- **Пакеты в монолитной системе**. В монолитных системах правильное разделение на пакеты может значительно улучшить связность. Например, отдельный пакет для работы с базой данных должен иметь высокую связность внутри себя, чтобы все его компоненты были направлены на работу с данными.
|
||
- Классы в [[ООП|объектно-ориентированном программировании]]. Классы с высокой связностью содержат методы, направленные на выполнение одной конкретной задачи, что упрощает их поддержку и тестирование.
|
||
|
||
**Преимущества высокой связности**
|
||
- **Повышение переиспользуемости**. Высокая связность модулей позволяет их легче переиспользовать, так как все необходимые функции сосредоточены в одном месте.
|
||
- **Упрощение модификации**. Модуль с высокой связностью легче модифицировать, так как все его компоненты работают вместе для достижения одной цели.
|
||
|
||
**Антипаттерны и частые ошибки**
|
||
- **Божественный объект (God Object)**. Это пример нарушения принципа высокой связности, когда один класс или модуль берет на себя слишком много обязанностей и имеет зависимости на многие другие части системы. Такой дизайн затрудняет понимание и модификацию кода.
|
||
|
||
**Рекомендации**
|
||
- [[Single Responsibility Principle|Принцип единственной ответственности]] (SRP). Каждый модуль или класс должен иметь одну четко определенную ответственность, что повышает связность и облегчает поддержку кода.
|
||
- Регулярный [[../efficiency/Рефакторинг кода|рефакторинг]]. Постоянное улучшение кода помогает повысить связность внутри модулей, устраняя излишние обязанности и сосредоточивая функции на одной задаче.
|
||
## Антипример микросервисной архитектуры
|
||
Рассмотрим пример интернет-магазина, в котором реализовано три разных вида доставки: доставка в пункт выдачи, доставка курьером и доставка в магазин. Для каждой из этих задач были созданы отдельные микросервисы: `PickupPointService`, `CourierDeliveryService` и `StoreDeliveryService`.
|
||
|
||
На первый взгляд, это выглядит как хороший подход, однако на практике каждое из этих решений может развиваться в разных направлениях и иметь различные бизнес-требования. В будущем может оказаться, что добавление новых функций в один из сервисов требует изменения логики и усложняет взаимодействие между сервисами, что может привести к дублированию бизнес-логики в нескольких местах.
|
||
|
||
Кроме того, чтобы посчитать время доставки, каждый из этих сервисов должен знать и запросить время комплектации заказа. Это означает, что одно и то же время комплектации будет запрашиваться несколько раз разными сервисами, что приводит к избыточным обращениям и усложняет координацию между сервисами.
|
||
|
||
В таких случаях объединение этой логики могло бы уменьшить сложность и избежать проблем с несогласованностью изменений в разных сервисах. Это пример того, когда дублирование и разделение по типу доставки могут изначально выглядеть оправданными, но на практике могут усложнить поддержку системы.
|
||
## Примеры кода
|
||
Высокая связность (Good Cohesion)
|
||
|
||
```java
|
||
public class UserService {
|
||
private final UserRepository userRepository;
|
||
|
||
public UserService(UserRepository userRepository) {
|
||
this.userRepository = userRepository;
|
||
}
|
||
|
||
public User createUser(String name, String email) {
|
||
// Логика создания пользователя
|
||
User user = new User(name, email);
|
||
return userRepository.save(user);
|
||
}
|
||
|
||
public User getUserById(Long id) {
|
||
// Логика получения пользователя по ID
|
||
return userRepository.findById(id);
|
||
}
|
||
}
|
||
```
|
||
|
||
В этом примере класс `UserService` имеет высокую связность, так как все его методы связаны с управлением пользователями и взаимодействием с `UserRepository`. Высокая связность делает класс легче поддерживаемым, поскольку все функции находятся в одном месте, что упрощает внесение изменений и тестирование, а также способствует лучшей организации кода и уменьшению сложности.
|
||
|
||
Низкая связность (Bad Cohesion)
|
||
|
||
```java
|
||
public class UserUtility {
|
||
private final UserRepository userRepository;
|
||
private final EmailService emailService;
|
||
|
||
public UserUtility(UserRepository userRepository, EmailService emailService) {
|
||
this.userRepository = userRepository;
|
||
this.emailService = emailService;
|
||
}
|
||
|
||
public User createUser(String name, String email) {
|
||
// Логика создания пользователя
|
||
User user = new User(name, email);
|
||
return userRepository.save(user);
|
||
}
|
||
|
||
public void sendWelcomeEmail(User user) {
|
||
// Логика отправки приветственного письма
|
||
emailService.sendEmail(user.getEmail(), "Welcome!");
|
||
}
|
||
|
||
public void deleteUser(Long id) {
|
||
// Логика удаления пользователя
|
||
userRepository.deleteById(id);
|
||
}
|
||
}
|
||
```
|
||
|
||
В этом примере класс `UserUtility` имеет низкую связность, так как в нем сочетаются разные обязанности: управление пользователями, отправка email, удаление пользователей. Такой класс сложно поддерживать и тестировать, так как его методы не связаны одной конкретной задачей.
|
||
|
||
***
|
||
## Мета информация
|
||
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
|
||
**Родитель**::
|
||
**Источник**::
|
||
**Создана**:: [[2024-11-24]]
|
||
**Автор**::
|
||
### Дополнительные материалы
|
||
-
|
||
|
||
### Дочерние заметки
|
||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||
|