[스프링부트 핵심 가이드] 책을 기준으로 작성하였습니다.
🍀 레이어드 아키텍처란
애플리케이션의 컴포넌트를 유사 관심사를 기준으로 레이어로 묶어 수평적으로 구성한 구조를 의미한다. 레이어드 아키텍처는 여러 방면에 쓰이는 개념이며, 어떻게 설계하냐에 따라 용어와 계층의 수가 달라진다.
일반적으로 레이어드 아키텍처는 3 계층 또는 4 계층 구성을 의미한다. 이 차이는 인프라(데이터베이스) 레이어의 추가 여부로 결정된다.
여기서는 3 계층 레이어드 아키텍처를 기준으로 설명해 보자.
✅ 프레젠테이션 계층
- 애플리케이션의 최상단 계층으로, 클라이언트의 요청을 해석하고 응답하는 역할을 한다. (사용자와 시스템 간의 상호작용)
- 사용자 인터페이스(UI) 또는 API를 제공한다.
- 사용자의 입력값을 검증하고, 비지니스 로직에 따라 결과를 표시한다.
- 프레젠테이션 계층은 별도의 비즈니스 로직을 포함하지 않고, 비즈니스 계층으로 요청을 위임하고 받은 결과를 응답하는 역할만 수행한다.
✅ 비즈니스 계층
- 프레젠테이션 계층과 도메인 계층 사이에서 비즈니스 로직을 처리한다.
- 애플리케이션의 기능을 정의하고 세부 작업을 수행하는 도메인 객체를 통해 업무를 위임하는 역할을 수행한다.
- DDD(Domain-Driven Design) 기반의 아키텍처에서는 비즈니스 로직에 도메인이 포함되기도 하고, 별도로 도메인 계층을 두기도 한다.
✅ 데이터 접근 계층
- 데이터베이스에 접근하는 일련의 작업을 수행한다.
각 레이어의 특징을 기반으로 하는 설계를 "레이어드 아키텍처 기반 설계"라 하며 다음과 같은 특징을 가진다.
- 각 레이어는 가장 가까운 하위 레이어의 의존성을 주입받는다.
- 각 레이어는 관심사에 따라 묶여 있으며, 다른 레이어를 침범하지 않는다.
- 각 컴포넌트 역할이 명확하므로 코드의 가독성과 기능 구현에 유리
- 코드의 확장성이 좋아진다.
- 각 레이어가 독립적으로 작성되면 다른 레이어와의 의존성을 낮춰 단위 테스트에 용이해진다.
🍀 스프링 레이어드 아키텍처란
스프링 부트의 기본 설정인 spring-boot-starter-web의 의존성을 사용한다면 기본적으로 스프링 MVC 구조를 띠게 된다.
위 그림과 같이 스프링 MVC를 사용하면 Model-View-Controller의 구조로 View와 Controller는 프레젠테이션 계층영역이며, Model은 비즈니스 계층과 데이터 접근 계층 영역으로 구분된다. 다만 스프링 MVC 모델로 레이어드 아키텍처를 구성하려면 역할의 세분화가 필요하다.
비즈니스 계층에 서비스를 배치하여 엔티티와 같은 도메인 객체의 비지니스 로직을 조합하게 하고, 데이터 접근 계층에는 DAO(JPA에서는 Repository)를 배치해 도메인을 관리한다.
✅ 프레젠테이션 계층
- 상황에 따라 유저 인터페이스(UI) 계층이라고도 한다.
- 클라이언트와의 상호작용(접점) 역할을 수행한다.
- 클라이언트로부터 데이터와 함께 요청을 받고 처리 결과를 응답으로 전달하는 역할수행한다.
✅ 비즈니스 계층
- 상황에 따라 서비스(Service) 계층이라고도 한다.
- 핵심 비지니스 로직을 구현하는 역할을 한다.
- 트랜잭션 처리나 유효성 검사 등의 작업도 수행한다.
✅ 데이터 접근 계층
- 상황에 따르 영속(Persistence) 계층이라고도 한다.
- 데이터베이스에 접근해야 하는 작업을 수행한다.
- 그림에서는 DAO라고 컴포넌트를 표현했지만, JPA에서는 DAO 역할을 리파지토리가 수행하므로 리파지토리로 대체할 수 있다.
🍀 추가적으로
레이어드 아키텍처는 일반적인 계층 구조를 기반으로 필요에 따라 변형하여 사용한다. 가장 중요한 부분은 비즈니스 계층 영역인데, 비즈니스 로직을 어디서 담당할지 결정하고 설계하는 것이 좋다.
일반적으로 비즈니스 로직은 도메인 계층에서 담당한다. 서비스 계층에서 처리해야 한다고 오해하고 있지만 서비스는 트렌젝션과 도메인의 순서만을 보장한다.
스프링에서는 JPA를 사용하면 @Entity를 정의한 클래스가 도메인 객체가 되며, 이곳을 기준으로 비즈니스 로직을 설계하면 된다.
'Framework > Spring' 카테고리의 다른 글
[Spring] POST, PUT, DELETE API (0) | 2023.10.11 |
---|---|
[Spring] GET API를 구현하는 다양한 방법 (0) | 2023.10.06 |
[Spring] REST API 란? (0) | 2023.10.05 |
[Spring] 스프링 부트의 동작 방식 (0) | 2023.10.05 |
[Spring] 스프링 프레임워크 vs 스프링 부트 (0) | 2023.10.04 |