digital-garden/dev/architecture/Связность.md

9.6 KiB
Raw Blame History

aliases tags date
Cohesion
связности
связность
maturity/🌱
2024-11-24

Связность (cohesion) — это мера того, насколько функции внутри одного модуля связаны друг с другом и работают вместе для выполнения конкретной задачи. Высокая связность означает, что модуль фокусируется на одной задаче и все его компоненты направлены на достижение этой цели. Например, модуль обработки платежей включает только функции, связанные с платежами, что делает его логически целостным.

Примеры применения

  • ../../../../wiki/zero/00 Микросервисная архитектура. Сервис с высокой связностью сосредоточен на конкретной бизнес-задаче, например, управлении пользователями или платежами. Например, сервис управления пользователями может добавлять, обновлять и удалять пользователей без взаимодействия с другими сервисами, что делает его легким в поддержке. Все классы в микросервисе направлены на решение этих задач.
  • Пакеты в монолитной системе. В монолитных системах правильное разделение на пакеты может значительно улучшить связность. Например, отдельный пакет для работы с базой данных должен иметь высокую связность внутри себя, чтобы все его компоненты были направлены на работу с данными.
  • Классы в ООП. Классы с высокой связностью содержат методы, направленные на выполнение одной конкретной задачи (Single Responsibility Principle), что упрощает их поддержку и тестирование.

Преимущества высокой связности

  • Повышение переиспользуемости. Высокая связность модулей позволяет их легче переиспользовать, так как все необходимые функции сосредоточены в одном месте.
  • Упрощение модификации. Модуль с высокой связностью легче модифицировать, так как все его компоненты работают вместе для достижения одной цели.

Антипаттерны и частые ошибки

  • Божественный объект (God Object). Это пример нарушения принципа высокой связности, когда один класс или модуль берет на себя слишком много обязанностей и имеет зависимости на многие другие части системы. Такой дизайн затрудняет понимание и модификацию кода.

Рекомендации

  • Single Responsibility Principle (SRP). Каждый модуль или класс должен иметь одну четко определенную ответственность, что повышает связность и облегчает поддержку кода.
  • Регулярный ../efficiency/Рефакторинг кода. Постоянное улучшение кода помогает повысить связность внутри модулей, устраняя излишние обязанности и сосредоточивая функции на одной задаче.

Антипример микросервисной архитектуры

Рассмотрим пример интернет-магазина, в котором реализовано три разных вида доставки: доставка в пункт выдачи, доставка курьером и доставка в магазин. Для каждой из этих задач были созданы отдельные микросервисы: PickupPointService, CourierDeliveryService и StoreDeliveryService.

На первый взгляд, это выглядит как хороший подход, однако на практике каждое из этих решений может развиваться в разных направлениях и иметь различные бизнес-требования. В будущем может оказаться, что добавление новых функций в один из сервисов требует изменения логики и усложняет взаимодействие между сервисами, что может привести к дублированию бизнес-логики в нескольких местах.

Кроме того, чтобы посчитать время доставки, каждый из этих сервисов должен знать и запросить время комплектации заказа. Это означает, что одно и то же время комплектации будет запрашиваться несколько раз разными сервисами, что приводит к избыточным обращениям и усложняет координацию между сервисами.

В таких случаях объединение этой логики могло бы уменьшить сложность и избежать проблем с несогласованностью изменений в разных сервисах. Это пример того, когда дублирование и разделение по типу доставки могут изначально выглядеть оправданными, но на практике могут усложнить поддержку системы.

Примеры кода

Высокая связность (Good Cohesion)

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)

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 Архитектура ПО Родитель:: Источник:: Создана:: 2024-11-24 Автор::

Дополнительные материалы

Дочерние заметки