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. Частая ошибка — путать многослойную архитектуру с гексагональной, не видя принципиальной разницы в направлении зависимостей.