--- 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]] **Автор**:: ### Дополнительные материалы - ### Дочерние заметки