백엔드를 개발하면서 다양한 패키지 구조를 접한다.
복잡도, 프로젝트 규모, 조직원들의 합의에 의해 다양한 아키텍처를 접하는데,
주로 사용되는 패키지 구조를 비교하며 알아보자.
1. 왜 패키지 구조를 가지는가?
초창기 소프트웨어 개발분야(특히 자바, C#)에서는 계층형 구조(layered architecture)를 선호했다.
그 이유는 그 당시(1990년대)에는 소프트웨어를 개발함에 있어서
명확한 책임 분리가 최우선 목표였다.
그리고 그에따라 3개의 계층구조가 자연스럽게 나왔고,
- Controller (Presentation): 화면이나 요청을 처리
- Service (Business Logic): 핵심 로직 담당
- Repository/DAO (Data Access): DB와 통신
이렇게 3개의 계층으로 주로 사용했다.
특히 IMB, Microsoft 같은 회사들이 기업용 소프트웨어 개발 표준으로 위 아키텍처를 삼아서,
전세계적으로 더 퍼진게 있다.
그 이후에도
레이어드 아키텍처의 한계점 (서비스가 커질수록 Controller, Serivce, Repository가 비대해짐)과 함께
도메인 중심 구조로 발전하고,
더 복잡해진 비즈니스 도메인을 가진 시스템을 더 효과적으로 제어하기 위해
Hexagonal 아키텍처로 발전하고 있다.
2. 3가지 아키텍처
2.1 layered architecture
레이어드 아키텍처는 가장 보편적인 구조로서 CRUD 기반 서비스에서 가장 많이 볼 수 있다.
주로 아래의 패키지 구조를 따르며, 크게 Controller, Serivce, Repository를 분리하는게 특징이다.
com.example.project
├── controller // API 요청/응답 처리
├── service // 비즈니스 로직
├── repository // DB 접근 (JPA, MyBatis 등)
├── domain // 엔티티, VO, DTO
├── exception // 예외 정의
├── config // 설정 (Spring, Security, Swagger 등)
└── util // 공통 유틸
장점:
- 이해하기 쉽고 팀원 간 합의가 간단함
- 소규모 프로젝트에 적합하고 가장 대중적인 아키텍처 패턴임
단점:
- 규모가 커질수록 Controller, Serivce, Repository 관리가 어려워짐
2.2 Domain-Oriented Architecture (도메인 중심 구조)
도메인(비즈니스 개념)별로 묶는 구조로서
일정 규모 이상의 서비스는 이걸 많이 사용한다.
레이어드 아키텍처가 비대해지는 문제를 도메인 중심으로 관리하여 복잡성을 낮춘다.
아래의 예시와 같은 형태를 띠며, 레이어드 아키텍처와 달리
상위에 도메인(비즈니스 개념) 내부에 관리된다.
com.example.project
├── user
│ ├── controller
│ ├── service
│ ├── repository
│ ├── domain
│ └── dto
├── order
│ ├── controller
│ ├── service
│ ├── repository
│ ├── domain
│ └── dto
├── payment
│ ├── controller
│ ├── service
│ ├── repository
│ └── domain
├── global // 공통 설정, 예외, 유틸, 인터셉터 등
│ ├── config
│ ├── exception
│ └── util
장점:
- 도메인 경계가 명확해서 유지보수 용이
- 마이크로서비스로 분리할 때 자연스러움
- 대규모 프로젝트에 적합
단점:
- 초기에 구조 설계가 다소 복잡함
2.3 Hexagonal Architecture (헥사고날 아키텍처)
"비즈니스 로직(Core)은 외부 세계(UI, DB, 메시지, API 등)에 의존하지 않아야 한다"는 코어 아이디어 아래에
시스템을 내부(Core)와 외부(Adapters)로 구분
주로 아래와 같은 패턴을 띄며
비즈니스 로직이 외부(웹, DB, 메시징 등)를 모르게 하는 것이 핵심이다.
com.example.project
├── application # UseCase(입력 포트), 비즈니스 흐름 제어
├── domain # 순수 비즈니스 로직 (엔티티, 규칙, 정책)
├── infrastructure # 외부 시스템(DB, 외부 API 등 어댑터)
├── interface # 입출력 어댑터 (Controller, REST, CLI 등)
└── global # 공통 설정, 예외, 설정 등
핵심 구성요소는 다음과 같다.
| 구성 요소 | 역할 |
| Domain | 순수 비즈니스 로직 |
| Ports | 외부 의존성에 대한 인터페이스 |
| Adapters | 실제 구현체 (DB, REST API, Kafka 등) |
장점:
- Domain은 외부 기술들과 완전히 분리
- 외부 기술 교체 용이 (e.g., RDB → NoSQL 교체 시 Adapter만 수정)
- MSA 전환이 쉬움
단점:
- 설계 복잡도와 초기 비용이 큼
- 단기적 개발에는 상대적으로 시간이 더 많이 소요
- 팀 전체가 아키텍처 철학을 이해해야 통일성 유지 가능
서비스의 규모와 개발 역사에 따른 백엔드 패키지 아키텍처의 변화를 보았다.
가장 익숙하고 대중적인 아키텍처 3가지를 비교해보았고
모두 사용해보진 않았지만 서비스 규모가 커짐에 따라 아키텍처의 복잡성도 같이 증가했다.
결론
메이저 서비스는 점점더 복잡해질것이며,
그런 복잡한 환경을 제어할 아키텍처가 또 등장할것이다.
우리 서비스의 규모에 맞는 아키텍처를 채택해 사용하자.
'공부 > 디자인 패턴' 카테고리의 다른 글
| 팩토리 메소드 패턴이란? (0) | 2024.06.06 |
|---|