Карта / Архитектура / Слоистая архитектура

Слоистая архитектура

Слоистая (layered) архитектура — самый распространённый способ организации кода в Java-приложениях. Код делится на слои, каждый из которых отвечает за свою область и зависит только от слоя ниже.

Классические три слоя в Spring Boot:

┌─────────────────────────────┐
│  Controller (@RestController) │  ← HTTP: принять запрос, вернуть ответ
├─────────────────────────────┤
│  Service (@Service)          │  ← Бизнес-логика: что нужно сделать
├─────────────────────────────┤
│  Repository (@Repository)    │  ← Работа с данными: как сохранить/получить
└─────────────────────────────┘

Правило зависимостей: Controller знает о Service, Service знает о Repository. Но не наоборот. Repository не должен зависеть от Controller — иначе слои теряют смысл.

@RestController  // HTTP-слой
class UserController {
    private final UserService service;
    UserDto get(@PathVariable Long id) { return service.getUser(id); }
}

@Service         // Бизнес-слой
class UserService {
    private final UserRepository repo;
    UserDto getUser(Long id) { return toDto(repo.findById(id)); }
}

@Repository      // Данные
interface UserRepository extends JpaRepository<User, Long> {}
Копнуть глубже

DTO и маппинг между слоями. Лучшая практика — каждый слой работает со своими объектами:

  • Entity — для JPA/Repository (знает про @Column, @Table)
  • DTO — для Controller (что отдаём клиенту, что принимаем)
  • Domain объект — для Service (чистая бизнес-логика без JPA-аннотаций)

Маппинг между ними — через конструкторы, или MapStruct (генерирует маппер автоматически). Это защищает от случайного попадания внутренних деталей (пароля, служебных полей) в ответ API.

Проблема «жирного сервиса». В реальных проектах вся бизнес-логика часто собирается в Service — он разрастается до тысяч строк. Чистая архитектура (см. тему «Чистая архитектура») предлагает решение: выделить Domain Layer с чистыми бизнес-объектами и use cases, отделив их от деталей реализации (Spring, JPA).

Тестирование по слоям. Каждый слой тестируется изолированно:

  • @WebMvcTest — только Controller (MockMvc, без реального сервиса)
  • @Service — чистый unit test с Mockito (без Spring)
  • @DataJpaTest — только Repository (реальная встроенная БД)
  • @SpringBootTest — интеграционный тест всех слоёв вместе
🎤 Закрыл тему, если можешь объяснить:
• три слоя стандартного Spring Boot приложения и зону ответственности каждого;
• правило зависимостей между слоями и зачем DTO (если дошёл до 2-го слоя).