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

Что такое чистая архитектура?

2.0 Middle🔥 181 комментариев
#Микросервисы и архитектура

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

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

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

Что такое Чистая Архитектура (Clean Architecture)?

Чистая Архитектура — это концепция организации кода, предложенная Робертом Мартином (Uncle Bob), которая направлена на создание гибких, поддерживаемых и независимых от фреймворков, UI и баз данных программных систем. Её основная цель — разделение ответственности (Separation of Concerns) и соблюдение правила зависимости (Dependency Rule): зависимости в коде должны быть направлены внутрь, к ядру системы, а внешние детали (как база данных или веб-интерфейс) зависят от внутренних бизнес-правил, а не наоборот.

Ключевые принципы и слои

Чистая архитектура организует код в концентрические слои (или круги), где каждый внешний слой зависит от внутреннего, но не наоборот. Вот основные слои, от внутренних к внешним:

1. Сущности (Entities)

Это ядро системы, содержащее бизнес-правила и ключевые объекты предметной области (например, User, Order, Product). Они не зависят ни от чего внешнего — ни от баз данных, ни от фреймворков, ни даже от вариантов использования.

// Пример сущности в Go
package entity

type User struct {
    ID        string
    Email     string
    FirstName string
    LastName  string
}

func (u *User) ValidateEmail() error {
    // Бизнес-правило валидации email
    if !strings.Contains(u.Email, "@") {
        return errors.New("invalid email format")
    }
    return nil
}

2. Сценарии использования (Use Cases)

Содержат бизнес-логику приложения, реализующую конкретные сценарии (например, "создание заказа", "аутентификация пользователя"). Они зависят только от сущностей, но не от внешних деталей.

// Пример use case в Go
package usecase

import "project/entity"

type UserRepository interface {
    Save(user *entity.User) error
    FindByEmail(email string) (*entity.User, error)
}

type CreateUserUseCase struct {
    repo UserRepository
}

func (uc *CreateUserUseCase) Execute(email, firstName, lastName string) error {
    user := &entity.User{
        Email:     email,
        FirstName: firstName,
        LastName:  lastName,
    }
    
    if err := user.ValidateEmail(); err != nil {
        return err
    }
    
    return uc.repo.Save(user)
}

3. Интерфейсы адаптеров (Interface Adapters)

Преобразуют данные между форматами, удобными для use cases и внешними системами. Сюда входят:

  • Контроллеры (обработчики HTTP-запросов)
  • Гейтвеи/репозитории (интерфейсы для работы с данными)
  • Презентеры (подготовка данных для отображения)
// Пример контроллера и репозитория в Go
package handler

import "project/usecase"

type UserHandler struct {
    createUserUseCase *usecase.CreateUserUseCase
}

func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
    var request struct {
        Email     string `json:"email"`
        FirstName string `json:"first_name"`
        LastName  string `json:"last_name"`
    }
    
    if err := c.BodyParser(&request); err != nil {
        return c.Status(400).JSON(map[string]string{"error": "invalid request"})
    }
    
    err := h.createUserUseCase.Execute(request.Email, request.FirstName, request.LastName)
    if err != nil {
        return c.Status(500).JSON(map[string]string{"error": err.Error()})
    }
    
    return c.Status(201).JSON(map[string]string{"status": "user created"})
}

4. Фреймворки и драйверы (Frameworks & Drivers)

Внешний слой, содержащий конкретные реализации: базы данных (PostgreSQL, MongoDB), веб-фреймворки (Fiber, Gin), внешние API и т.д.

// Пример реализации репозитория для PostgreSQL
package postgres

import (
    "project/entity"
    "gorm.io/gorm"
)

type UserRepository struct {
    db *gorm.DB
}

func (r *UserRepository) Save(user *entity.User) error {
    return r.db.Create(user).Error
}

func (r *UserRepository) FindByEmail(email string) (*entity.User, error) {
    var user entity.User
    err := r.db.Where("email = ?", email).First(&user).Error
    return &user, err
}

Преимущества Чистой Архитектуры в Go

  • Тестируемость: Бизнес-логику можно тестировать изолированно, без зависимости от внешних систем.
  • Независимость от фреймворков: Миграция с одного фреймворка на другой затрагивает только внешний слой.
  • Гибкость и поддерживаемость: Изменения в одном слое минимально затрагивают другие.
  • Чёткая структура проекта: Каждый компонент имеет строго определённую ответственность.
  • Отсроченные решения: Можно отложить выбор конкретных технологий (БД, фреймворков).

Практическое применение в Go-проектах

В экосистеме Go Чистая Архитектура часто реализуется через:

  1. Интерфейсы для определения контрактов между слоями
  2. Внедрение зависимостей (Dependency Injection) для связывания слоев
  3. Структуру папок, отражающую слои архитектуры:
project/
├── cmd/              # Точки входа
├── internal/         # Внутренние пакеты
│   ├── entity/       # Сущности
│   ├── usecase/      # Сценарии использования
│   ├── repository/   # Интерфейсы репозиториев
│   └── handler/      # HTTP-обработчики
├── pkg/              # Переиспользуемые пакеты
└── infrastructure/   # Конкретные реализации (PostgreSQL, Redis и т.д.)

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

Что такое чистая архитектура? | PrepBro