Gymterview
junior

Что такое многослойная (layered) архитектура

Многослойная (layered) архитектура — один из наиболее распространённых архитектурных паттернов, при котором система разделяется на горизонтальные слои, каждый из которых выполняет определённую роль. Каждый слой зависит только от нижележащего. Это похоже на этажи здания: каждый этаж опирается на тот, что под ним, и не зависит от того, что над ним.

Классическая трёхслойная архитектура в Spring-приложении

Пример
        HTTP-запрос
             │
             ▼
┌─────────────────────────┐
│   Controller (Web слой) │  ← Принимает запросы, валидирует входные данные,
│   @RestController       │     возвращает ответы (DTO)
└────────────┬────────────┘
             │
             ▼
┌─────────────────────────┐
│   Service (Бизнес-слой) │  ← Содержит бизнес-логику,
│   @Service              │     оркестрирует вызовы
└────────────┬────────────┘
             │
             ▼
┌─────────────────────────┐
│  Repository (Слой       │  ← Работает с БД,
│  доступа к данным)      │     выполняет CRUD-операции
│  @Repository            │
└────────────┬────────────┘
             │
             ▼
        ┌─────────┐
        │   БД    │
        └─────────┘

Пример на Java (Spring Boot)

Пример кода
// Controller — Web-слой
@RestController
@RequestMapping("/api/accounts")
public class AccountController {

    private final AccountService accountService;

    public AccountController(AccountService accountService) {
        this.accountService = accountService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<AccountDto> getAccount(@PathVariable Long id) {
        AccountDto account = accountService.findById(id);
        return ResponseEntity.ok(account);
    }

    @PostMapping("/transfer")
    public ResponseEntity<Void> transfer(@RequestBody @Valid TransferRequest request) {
        accountService.transfer(request);
        return ResponseEntity.ok().build();
    }
}

// Service — бизнес-слой
@Service
@Transactional
public class AccountService {

    private final AccountRepository accountRepository;

    public AccountService(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    public AccountDto findById(Long id) {
        Account account = accountRepository.findById(id)
            .orElseThrow(() -> new AccountNotFoundException(id));
        return AccountMapper.toDto(account);
    }

    public void transfer(TransferRequest request) {
        Account from = accountRepository.findById(request.getFromId())
            .orElseThrow(() -> new AccountNotFoundException(request.getFromId()));
        Account to = accountRepository.findById(request.getToId())
            .orElseThrow(() -> new AccountNotFoundException(request.getToId()));

        from.withdraw(request.getAmount());
        to.deposit(request.getAmount());

        accountRepository.save(from);
        accountRepository.save(to);
    }
}

// Repository — слой доступа к данным
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
    List<Account> findByClientId(Long clientId);
}

Правила многослойной архитектуры

  • Каждый слой зависит только от слоя непосредственно ниже.
  • Слой не должен знать о вышестоящем слое.
  • Слой может быть заменён без влияния на остальные (при соблюдении контракта).
  • Бизнес-логика сосредоточена в Service-слое.

Плюсы

  • Простота понимания и низкий порог входа.
  • Разделение ответственности.
  • Возможность независимого тестирования каждого слоя.

Минусы

  • Зависимость бизнес-логики от инфраструктуры (Service знает про Repository).
  • Склонность к «анемичной» модели данных (логика в сервисах, сущности — просто контейнеры данных).
  • При большом количестве модулей слои «размываются».

На собеседовании: Важно показать, что вы понимаете правило зависимостей (сверху вниз) и можете объяснить, почему Controller не должен обращаться напрямую к Repository. Частая ошибка — путать многослойную архитектуру с гексагональной, не видя принципиальной разницы в направлении зависимостей.