← Назад к вопросам

Что такое бизнес-логика?

1.0 Junior🔥 231 комментариев
#Микросервисы и архитектура

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое бизнес-логика?

Бизнес-логика (Business Logic, Domain Logic) — это набор правил, алгоритмов и процессов, которые определяют, как данные создаются, отображаются, хранятся и изменяются в соответствии с требованиями предметной области (бизнес-правилами) приложения. Она представляет собой ядро функциональности программной системы, непосредственно реализующее её предназначение — автоматизацию бизнес-процессов. По сути, это код, который отвечает на вопрос «ЧТО делает приложение?», в отличие от инфраструктурного кода, который отвечает на вопрос «КАК оно это делает?».

В архитектуре приложения бизнес-логика обычно выделяется в отдельный слой — доменный слой (Domain Layer) или слой бизнес-логики. Это центральный и самый важный слой, который не должен зависеть от деталей реализации внешних компонентов: базы данных, веб-фреймворка, UI или внешних API. Такой подход является ключевым принципом чистой архитектуры (Clean Architecture) и Domain-Driven Design (DDD).

Роль бизнес-логики в Go-приложениях

В Go, который часто выбирают для создания высоконагруженных и отказоустойчивых backend-систем, бизнес-логика должна быть:

  • Явной и читаемой: Go поощряет простоту и явное выражение намерений.
  • Протестированной: Бизнес-правила должны покрываться unit-тестами.
  • Независимой: Она не должна быть «размазана» по обработчикам HTTP-запросов (http.Handler) или смешана с кодом работы с базой данных.

Рассмотрим пример. Допустим, мы создаём сервис для банковского перевода.

Без выделенной бизнес-логики (антипаттерн): Код правил будет смешан с инфраструктурой, его сложно тестировать и изменять.

// ПЛОХО: Бизнес-логика зашита в обработчик HTTP
func TransferHandler(w http.ResponseWriter, r *http.Request) {
    var req TransferRequest
    json.NewDecoder(r.Body).Decode(&req)

    // Инфраструктура: Валидация входных данных (можно вынести)
    if req.Amount <= 0 {
        http.Error(w, "invalid amount", http.StatusBadRequest)
        return
    }

    // Инфраструктура: Начало транзакции в БД
    tx, _ := db.Begin()
    defer tx.Rollback()

    // Бизнес-логика №1: Проверка достаточности средств
    var balance float64
    tx.QueryRow("SELECT balance FROM accounts WHERE id = $1", req.FromID).Scan(&balance)
    if balance < req.Amount {
        http.Error(w, "insufficient funds", http.StatusConflict)
        return
    }

    // Инфраструктура: Операции с БД
    tx.Exec("UPDATE accounts SET balance = balance - $1 WHERE id = $2", req.Amount, req.FromID)
    tx.Exec("UPDATE accounts SET balance = balance + $1 WHERE id = $2", req.Amount, req.ToID)

    // Бизнес-логика №2: Логирование критической операции
    tx.Exec("INSERT INTO audit_log (event, amount) VALUES ('transfer', $1)", req.Amount)

    // Инфраструктура: Фиксация транзакции
    tx.Commit()
    w.WriteHeader(http.StatusOK)
}

С выделенным слоем бизнес-логики (рекомендуемый подход): Мы создаём доменные структуры, интерфейсы репозиториев и явно описываем правила.

// ХОРОШО: Доменные сущности и бизнес-правила вынесены в отдельный слой/пакет

// domain/account.go - Доменная сущность
type Account struct {
    ID      string
    Balance float64
}

func (a *Account) Withdraw(amount float64) error {
    // ЯВНОЕ БИЗНЕС-ПРАВИЛО: Нельзя списать сумму, превышающую баланс
    if amount > a.Balance {
        return errors.New("insufficient funds")
    }
    if amount <= 0 {
        return errors.New("amount must be positive")
    }
    a.Balance -= amount
    return nil
}

func (a *Account) Deposit(amount float64) error {
    // Бизнес-правило: Нельзя внести отрицательную сумму
    if amount <= 0 {
        return errors.New("amount must be positive")
    }
    a.Balance += amount
    return nil
}

// domain/service.go - Сервис (или Use Case) с бизнес-логикой
type TransferService struct {
    accounts Repository // Интерфейс, а не конкретная БД!
    auditor  Auditor
}

func (s *TransferService) Execute(fromID, toID string, amount float64) error {
    // 1. Получаем сущности (бизнес-объекты)
    fromAcc, err := s.accounts.FindByID(fromID)
    if err != nil { return err }
    toAcc, err := s.accounts.FindByID(toID)
    if err != nil { return err }

    // 2. Последовательно применяем бизнес-правила
    if err := fromAcc.Withdraw(amount); err != nil {
        return err // "insufficient funds" или "amount must be positive"
    }
    if err := toAcc.Deposit(amount); err != nil {
        return err
    }

    // 3. Сохраняем состояние
    if err := s.accounts.Save(fromAcc); err != nil {
        return err
    }
    if err := s.accounts.Save(toAcc); err != nil {
        return err
    }

    // 4. Выполняем побочный бизнес-процесс (логирование)
    return s.auditor.LogTransfer(fromID, toID, amount)
}

Ключевые характеристики бизнес-логики:

  • Предметно-ориентированность: Она оперирует терминами домена (Счёт, Перевод, Платеж, Заказ), а не техническими понятиями (JSON, HTTP-сессия, SQL-запрос).
  • Содержит правила валидации: Проверка корректности данных с точки зрения бизнеса (минимальный платёж, статус заказа для операции).
  • Реализует workflows (сценарии): Определяет последовательность шагов для выполнения операции (создание заказа → резервирование товара → списание средств).
  • Вычисляет результаты: Расчёт стоимости с учётом скидок, налогов, комиссий.
  • Инварианты (Invariants): Гарантирует целостность и непротиворечивость данных (например, баланс счёта не может быть отрицательным).

Где именно находится бизнес-логика в коде на Go?

Она может быть инкапсулирована в:

  1. Методах доменных структур (struct), как в примере с Account.Withdraw().
  2. Отдельных функциях или методах сервисов (Service, UseCase), которые координируют работу нескольких сущностей.
  3. Пакетах internal/domain, internal/business или internal/app, изолированных от внешнего мира в соответствии с правилами видимости Go.

Итог: Бизнес-логика — это сущность, ради которой создаётся приложение. В Go её следует явно выделять в коде, делая независимой от фреймворков и инфраструктуры. Это повышает тестируемость, сопровождаемость и позволяет безопасно изменять правила, не затрагивая способ взаимодействия с пользователем или тип используемой базы данных. Правильно организованная бизнес-логика — признак зрелой и качественной архитектуры backend-приложения.

Что такое бизнес-логика? | PrepBro