Что такое бизнес-логика в приложении?

Ответ

Бизнес-логика — это набор правил, ограничений и операций, которые определяют, как приложение обрабатывает данные для решения задач в конкретной предметной области (бизнесе). Это "мозг" приложения, который реализует основные бизнес-процессы.

Проще говоря, бизнес-логика отвечает на вопрос: "Что приложение должно делать с данными?", в отличие от других слоев, которые отвечают на вопросы "как показать данные?" (слой представления) или "где хранить данные?" (слой доступа к данным).

Ключевые характеристики:

  • Бизнес-правила: Формальные ограничения, например: "пользователь не может заказать больше 5 единиц товара", "скидка 10% применяется только для заказов свыше $100", "пароль должен содержать минимум 8 символов".
  • Бизнес-процессы (Workflows): Последовательность шагов для выполнения задачи, например: "регистрация пользователя" включает проверку email, хеширование пароля, сохранение в базу и отправку приветственного письма.
  • Преобразование данных: Расчеты, агрегации и изменения данных в соответствии с правилами. Например, расчет итоговой стоимости корзины с учетом налогов и скидок.

Где она находится в архитектуре бэкенда?

Обычно бизнес-логику стараются изолировать в отдельном слое, чтобы сделать систему более гибкой и тестируемой. Чаще всего это:

  • Сервисный слой (Service Layer): Координирует выполнение операций, обращаясь к репозиториям и другим сервисам. Часто содержит логику процессов.
  • Доменный слой (Domain Layer): В таких архитектурах, как DDD (Domain-Driven Design), бизнес-логика инкапсулируется непосредственно в доменных моделях (сущностях, объектах-значениях).

Пример на Go (логика в сервисном слое):

// OrderService содержит бизнес-логику, связанную с заказами.
type OrderService struct {
    orderRepo    OrderRepository
    userNotifier UserNotifier
}

// PlaceOrder реализует бизнес-процесс оформления заказа.
func (s *OrderService) PlaceOrder(userID int, items []Item) (*Order, error) {
    // Бизнес-правило №1: заказ не может быть пустым.
    if len(items) == 0 {
        return nil, errors.New("order must contain at least one item")
    }

    // Преобразование данных: расчет общей суммы.
    var total float64
    for _, item := range items {
        total += item.Price
    }

    // Бизнес-правило №2: проверка лимита на сумму заказа.
    const maxOrderAmount = 5000.0
    if total > maxOrderAmount {
        return nil, fmt.Errorf("order amount %.2f exceeds the limit of %.2f", total, maxOrderAmount)
    }

    // Взаимодействие с другими слоями (хранилище).
    order, err := s.orderRepo.Save(userID, items, total)
    if err != nil {
        return nil, err
    }

    // Часть бизнес-процесса: уведомить пользователя.
    s.userNotifier.SendOrderConfirmation(userID, order.ID)

    return order, nil
}