1. 레이어드 아키텍처란 무엇인가?
1-1. 개념 정의
레이어드 아키텍처(Layered Architecture)는 소프트웨어 시스템을 **기능적 역할에 따라 층(Layer)**으로 나누어 설계하는 가장 전통적이면서도 널리 사용되는 구조다. 일반적으로는 3계층 또는 4계층 구조로 나누며, 각 계층은 고유한 책임을 갖고 상위 계층에 서비스를 제공한다. 각 계층은 아래 계층에만 의존하도록 구성되어 구조적 안정성을 확보할 수 있다.
1-2. 구성 계층의 종류
가장 대표적인 구성은 다음과 같다:
- Presentation Layer (UI)
- Application Layer (Service)
- Domain Layer (Business Logic)
- Infrastructure/Data Layer (Persistence)
필요에 따라 Application Layer와 Domain Layer가 통합되기도 하며, 일부 프로젝트에서는 Security Layer, Caching Layer 등을 독립 계층으로 추가하기도 한다.
1-3. 아키텍처의 철학
레이어드 아키텍처는 책임 분리(SRP, 단일 책임 원칙)에 충실한 구조로, 각 계층이 자신의 역할만 충실히 수행하고 다른 계층과 느슨하게 결합되도록 한다. 이를 통해 시스템의 유지보수성, 테스트 용이성, 변경에 대한 유연성을 확보할 수 있다.
1-4. 실전 적용의 보편성
웹 기반 시스템, ERP, 공공기관 프로젝트, 중소규모 SaaS 서비스 등 다양한 환경에서 가장 흔하게 채택되는 아키텍처다. 특히 Java/Spring, .NET 기반의 엔터프라이즈 애플리케이션에서는 사실상 표준 구조로 간주되며, 실무에서 가장 많은 예제가 존재한다.
2. 각 계층의 역할과 책임
2-1. 프레젠테이션 계층 (UI Layer)
사용자 인터페이스를 제공하는 계층으로, 사용자의 요청을 받아 Application Layer로 전달하고, 그 결과를 시각적으로 표시하는 역할을 한다. HTML, JavaScript, Vue, React 등의 기술이 주로 이 영역에 해당하며, API와의 통신도 이 계층에서 수행된다.
2-2. 애플리케이션 계층 (Application Layer)
비즈니스 로직을 호출하고 트랜잭션을 관리하는 조정자 역할을 수행한다. 프레젠테이션과 도메인 간의 다리 역할을 하며, 서비스(Service) 클래스나 유스케이스(UseCase) 구조로 표현된다. 외부 요청을 검증하고, 적절한 도메인 로직을 실행하며, 리턴 값을 가공하는 책임이 있다.
2-3. 도메인 계층 (Domain Layer)
시스템의 핵심 규칙, 비즈니스 로직을 담당한다. 가장 중요한 계층이며, 외부 변화에 가장 덜 의존해야 한다. 엔티티(Entity), 밸류(Value Object), 도메인 서비스, 애그리거트 등으로 구성되며, 테스트가 가장 활발히 이루어져야 하는 부분이다. 모든 정책과 판단은 이 계층에서 결정되어야 한다.
2-4. 인프라 계층 (Infrastructure Layer)
DB, 메시지 큐, 외부 API 등 실제 구현 및 기술 의존이 필요한 요소를 담당한다. Repository, DAO, FileStorage, KafkaProducer 등이 이 영역에 속한다. 아키텍처 상에서 가장 아래 계층에 존재하며, 도메인 로직에서 의존하지 않도록 설계되어야 한다.
3. 장점: 명확한 책임 분리와 유지보수성
3-1. 단일 책임 원칙에 부합
레이어드 아키텍처는 각 계층에 명확한 역할을 부여함으로써 단일 책임 원칙(SRP) 을 실천하기에 가장 이상적인 구조 중 하나다. 프레젠테이션 계층은 사용자 요청을 수신하고, 응답을 반환하는 데만 집중한다. 애플리케이션 계층은 외부 요청을 도메인 계층에 연결해주는 조정자 역할에 집중하며, 도메인 계층은 비즈니스 규칙을 정의하고 실행하는 데 전념한다.
이러한 구조는 책임의 중복을 방지하고, 불필요한 로직이 끼어드는 것을 차단한다. 예를 들어, DB 로직이 UI 코드에 섞이거나, 비즈니스 정책이 컨트롤러 안에 포함되는 현상은 구조적으로 차단된다. 결과적으로 코드 간섭이 줄고, 이해도와 유지보수성이 획기적으로 향상된다.
3-2. 테스트 용이성 향상
테스트 가능한 설계는 아키텍처의 중요한 기준이다. 레이어드 아키텍처는 계층마다 책임이 분리되어 있어 테스트 대상을 명확하게 정의할 수 있다. 도메인 계층은 외부 의존성 없이 순수 자바 코드(Pojo, Kotlin class 등)로 작성되므로 단위 테스트(Unit Test)가 쉽다. 테스트 중에는 인프라 계층을 Stub 또는 Mock으로 대체할 수 있으며, 애플리케이션 계층은 통합 테스트 수준에서 검증하면 된다.
특히 DDD 기반 레이어 구조에서는 도메인 규칙이 명확히 분리되어 있기 때문에, 요구사항 변경에 따른 테스트 영향 범위를 빠르게 파악할 수 있다. 또한 테스트 시나리오를 계층별로 나누어 작성할 수 있어 테스트 자동화도 용이하다. 이는 DevOps 환경에서 CI/CD 파이프라인에 테스트를 통합할 때 매우 유리하게 작용한다.
3-3. 유지보수성과 변경 용이성
레이어드 아키텍처는 변화에 강한 설계를 가능하게 한다. 예를 들어, 프론트엔드에서 Vue.js 대신 React로 UI를 변경하더라도, 하위 계층인 도메인이나 인프라에는 전혀 영향을 주지 않는다. 마찬가지로, RDB를 MongoDB 같은 NoSQL로 바꾸더라도 UI와 도메인 로직은 수정 없이 재사용할 수 있다.
이런 구조적 독립성은 비즈니스 변화에 빠르게 대응하고, 새로운 요구사항을 기존 코드와 격리하여 적용하는 데 유리하다. 예를 들어, 주문 로직에 새 할인 정책이 추가되더라도, 도메인 계층만 수정하면 되고 프레젠테이션이나 DB 구조는 건드릴 필요가 없다. 코드 파급 범위가 작아지면서, 버그 발생률도 자연히 줄어든다.
3-4. 교육 및 협업에 용이 (관점: 신입 및 역할 중심)
레이어드 아키텍처는 계층별 책임이 명확하기 때문에 신입 개발자나 외부 인력의 온보딩이 빠르고 수월하다. 전체 시스템을 파악하지 못해도 각 계층의 역할만 이해하면 업무에 투입 가능하다. 예를 들어 프론트엔드 개발자는 컨트롤러와 뷰 계층만, 백엔드 개발자는 도메인과 서비스 계층만 집중하면 된다.
또한 개발자, 기획자, 디자이너 등 역할 분리에 따라 인터페이스 계약(API, DTO 설계 등)을 기준으로 작업 범위를 분명히 나눌 수 있어, 역할 기반 협업에 유리한 구조라 할 수 있다. 이는 다기능 팀 구성이나 아웃소싱 협업에서 특히 강점을 보인다.
4. 레이어 간 통신 방식과 계층 간 의존성
4-1. 상향 호출 방식 (Downward Dependency)
레이어드 아키텍처는 상위 계층이 하위 계층을 호출하는 방식으로 작동한다. 예를 들어, 프레젠테이션 레이어는 서비스 레이어를 호출하고, 서비스 레이어는 도메인 또는 리포지토리 계층을 호출하는 구조다. 이러한 방식은 방향성이 명확하고 이해하기 쉬우며, 흐름 추적과 디버깅이 단순하다.
4-2. 의존 역전과 인터페이스 사용
전통적인 레이어드 구조에서는 인프라 계층이 도메인 계층을 의존하게 되지만, 이를 개선하기 위해 의존성 역전 원칙(DIP) 을 적용할 수 있다. 도메인 계층에서 리포지토리 인터페이스를 정의하고, 인프라 계층에서 그 구현체를 제공하는 방식이다. 이를 통해 도메인은 외부 기술 변화에 영향받지 않고 독립성을 유지할 수 있다.
4-3. 계층 간 DTO 및 Mapper 활용
계층 간 통신에서는 DTO(Data Transfer Object) 를 사용하는 것이 일반적이다. 예를 들어, UI에서 받은 입력을 애플리케이션 계층에 전달할 때, 도메인 모델과 혼용되지 않도록 별도의 DTO 객체를 사용한다. 이를 위해 MapStruct, ModelMapper 같은 매핑 도구를 활용하면 중복 코드를 줄이고 구조를 명확히 유지할 수 있다.
4-4. 계층 간 의존도 줄이기 전략
복잡한 시스템에서는 계층 간 호출이 많아지면서 결합도가 높아질 수 있다. 이를 방지하기 위해 이벤트 발행 방식(Publisher-Subscriber) 을 사용하는 것도 좋은 전략이다. 도메인 계층에서 비즈니스 이벤트를 발행하고, 애플리케이션 계층에서 이를 구독해 후속 처리를 하도록 하면 계층 간 연결을 느슨하게 유지할 수 있다.
5. 단점과 구조적 한계
5-1. 계층 간 중복 로직의 증가
레이어드 아키텍처는 각 계층이 책임을 분리하여 설계된다는 점에서 많은 장점을 갖지만, 그 구조적 분리에 따라 동일하거나 유사한 로직이 중복되는 문제가 자주 발생한다. 가장 대표적인 예는 입력값 검증, 권한 체크, 로깅, 예외 처리 같은 공통 로직이다.
예를 들어, 사용자가 주문을 요청하는 기능에서 요청 값에 대한 유효성 검사는 UI 계층, 서비스 계층, 도메인 계층 모두에서 반복될 수 있다. UI는 클라이언트 측에서 형식 검사를 수행하고, 서비스는 비즈니스 규칙 기반 검사를 하며, 도메인은 최종 제약을 보장한다. 이러한 중복은 개발과 유지보수의 부담을 가중시키고, 변화 발생 시 일관성 유지에 어려움을 초래한다. 또한 DTO와 Entity 간 변환 작업도 여러 계층에서 반복되며, 이를 위해 수많은 매핑 로직이 산재하게 된다. 매핑 자동화 도구(ModelMapper, MapStruct 등)가 도움을 줄 수 있지만, 이러한 도구 자체가 또 다른 관리 포인트로 작용하며 복잡도를 증가시킨다. 결국 이런 중복은 코드의 가독성과 유지보수성 모두에 부정적인 영향을 끼친다.
5-2. 도메인 중심 설계와의 충돌 (관점: 현실적인 기술 구조 한계 지적)
레이어드 아키텍처는 비즈니스 로직을 도메인 계층에 응집시키는 데 한계가 있다. 많은 프로젝트에서 도메인 계층은 단순 Entity의 집합으로만 존재하고, 핵심 로직이 서비스 계층에 몰리는 경향이 생긴다. 이 구조는 결국 '의미 없는 도메인 계층'을 만들고, 서비스가 모든 것을 담당하는 불균형 상태로 이어진다.
또한 도메인 계층이 서비스나 인프라와 강하게 결합되는 경우, 테스트 작성이 복잡해지고 리팩토링 비용이 급증한다. 이는 이상적인 도메인 주도 설계를 지향하더라도, 현실적인 기술 조직에서는 구조상 제대로 실현되기 어렵다는 현실적인 한계 지점을 보여준다.
5-3. 유연성 부족과 변화 대응력의 한계
레이어드 아키텍처는 구조적으로 기술 레이어 중심으로 구성되어 있기 때문에, 비즈니스 변화에 유연하게 반응하기 어려운 경우가 많다. 하나의 유스케이스(예: 주문 후 쿠폰 발행)를 구현하려 해도 프레젠테이션, 서비스, 도메인, 인프라 계층을 모두 수정해야 할 수 있다. 이는 단순한 기능 추가에도 수정 범위가 넓어지고 배포 리스크가 커지는 현상을 불러온다. 또한 유스케이스 중심 개발이 어렵기 때문에, 실제로는 서비스 계층에 if 문이 늘어나고 도메인 간 조건 분기가 포함되는 등, 서비스 계층 비대화(Service Bloat) 현상이 자주 발생한다. 이는 결국 단일 책임 원칙을 훼손하고 유지보수성을 저하시킨다.
대규모 기능 전환이나 A/B 테스트, 기능 토글 기반의 실험 환경 구성도 어렵다. 기능 단위로 독립된 경계를 정의하지 않았기 때문에, 부분 교체나 기능 전환이 계층 전체에 영향을 미치게 된다. 이런 구조는 DevOps, CI/CD, 블루그린 배포 같은 현대적인 운영 전략과 맞지 않게 작동할 수 있다.
5-4. 테스트 전략 복잡성과 흐름 추적의 부담
레이어드 아키텍처는 계층을 명확히 분리한 만큼, 테스트도 계층별로 수행해야 한다. 그러나 하나의 요청 흐름이 프레젠테이션 → 애플리케이션 → 도메인 → 인프라로 이어지다 보니, 단일 기능을 테스트하려 해도 여러 계층을 고려해야 하는 부담이 생긴다. 특히 통합 테스트를 설계할 때 계층 간 의존성과 Mocking 대상이 많아져 테스트 코드 자체가 복잡해진다. 또한, 계층별 인터페이스가 많고 객체 간 변환이 자주 발생하므로 디버깅 시 흐름 추적이 어렵다. 예를 들어, 사용자의 요청이 잘못된 결과를 반환했을 때, 이 오류가 UI의 문제인지, 서비스 로직의 버그인지, DB 질의의 문제인지 파악하기 어려워진다.
이러한 테스트 및 디버깅 부담은 QA 주기와 릴리즈 일정에도 영향을 주며, 시스템의 신뢰성을 떨어뜨리는 원인이 된다. 특히 레거시화된 프로젝트에서는 테스트 코드가 없는 상태로 계층이 뒤섞여 있어, 리팩토링이나 오류 수정이 매우 어려워지는 상황이 빈번하다.
6. 확장성과 모듈화 전략
6-1. 모듈화 기반 구조 분리
레이어드 아키텍처는 처음에는 단일 프로젝트 구조로 시작하지만, 시스템이 커지면 도메인별 또는 기능별 모듈화가 필수적이다. 초기에는 com.example.controller, service, domain, repository처럼 기술 기준으로 구성되지만, 점차 기능별로 분리된 모듈(예: member, order, payment) 구조로 확장된다. 이렇게 하면 하나의 기능을 하나의 독립 레이어드 구조로 유지할 수 있으며, 팀 단위 작업이나 코드 리팩토링 시 효율이 매우 높아진다. 특히 모듈을 maven/gradle의 멀티 모듈 구조로 분리하면, 의존성 관리도 체계적으로 이루어지며, 모듈 간 빌드 시간도 단축된다. 이는 마이크로서비스로 전환하기 전 단계로서도 유용한 기반이 된다.
6-2. 기능별 레이어드 아키텍처의 장점
전통적인 레이어드 구조는 기술 기준으로 나누는 경우가 많지만, 실무에서는 기능 또는 도메인 기준으로 레이어드를 구성하는 것이 더 유리한 경우가 많다. 예를 들어 회원, 상품, 주문 등 각 기능마다 독립적인 controller, service, domain, infra를 가진 소형 레이어드 구조로 구성하는 것이다.
이 구조의 장점은 기능 단위로 개발·배포·테스트·운영이 가능하다는 점이다. 도메인 중심 설계(DDD)에서도 이런 기능 중심 레이어 분리를 권장하며, 모놀리식 내에서의 마이크로서비스화(MSA-ready) 전략으로도 활용된다. 특히 트래픽이 많은 핵심 기능만 먼저 분리하여 독립 배포하거나, 팀 단위 책임 분리에도 효과적이다.
6-3. 수직 계층 확장 전략
시스템이 커질수록 단순한 3계층 구조로는 부족해진다. 예를 들어, 보안 처리, 캐싱, 메시징, API Gateway 연동, 이벤트 처리, 로그 수집 등과 같은 비즈니스 외적 기능이 요구된다. 이를 수직 계층으로 삽입하여 확장하는 것이 일반적인 전략이다. 예를 들어 서비스 계층 아래에 SecurityLayer, CacheService, MessageHandler를 삽입하고, 도메인 계층과 독립적으로 설계함으로써 비기능 요구사항을 구조화할 수 있다. 이를 통해 기존 레이어드의 명확한 계층 구분은 유지하면서, 복잡한 기능을 유연하게 흡수할 수 있다.
6-4. 구조적 일관성을 위한 패키지 및 네이밍 설계
레이어드 구조는 논리적 일관성과 물리적 디렉토리 구조가 맞물릴 때 가장 큰 효율을 발휘한다. 예를 들어 다음과 같이 패키지를 구성할 수 있다
com.example.member.controller
com.example.member.service
com.example.member.domain
com.example.member.infrastructure
이렇게 도메인 단위 + 계층 단위로 구조화하면 신규 기능 도입 시 코드를 어디에 작성해야 하는지 혼란이 없으며, 팀 내 리뷰와 협업 시 기준이 명확해진다. 또한 구조적 일관성은 IDE 코드 탐색, 테스트 클래스 분리, 자동 문서화에도 유리하다.
7. 다른 아키텍처 스타일과의 비교
7-1. 헥사고날 아키텍처와 비교
헥사고날 아키텍처(Hexagonal Architecture, Ports and Adapters)는 도메인 모델을 중심으로 외부와의 의존성을 완벽히 격리하는 구조다. 도메인을 중심으로 내부(Use Case, Domain Logic)와 외부(REST API, DB, 메시지 브로커 등)를 어댑터 형태로 구분한다. 반면, 레이어드 아키텍처는 위에서 아래로 흐르는 구조이며, 도메인을 외부 계층과 직접 분리하진 않는다.
헥사고날은 테스트가 매우 강력하며, 시스템 경계를 명확하게 설정할 수 있다는 점에서 뛰어나다. 하지만 적용이 어렵고 학습 비용이 높으며, 개발 초기 속도가 느리다. 레이어드는 구조는 단순하지만 외부 의존성과 결합이 상대적으로 높아, 테스트가 어렵고 도메인이 쉽게 오염될 수 있다.
7-2. 클린 아키텍처와의 차이 (관점: 철학적 차이 중심)
클린 아키텍처는 구조의 핵심을 도메인 모델의 불변성과 독립성에 둔다. 모든 의존성은 바깥에서 안쪽으로 향해야 하며, 도메인 로직은 외부 환경(Database, Framework, UI 등)에 영향을 받지 않아야 한다. 이런 철학은 SRP, OCP, DIP 등의 원칙을 구현하는 데 집중된다.
반면, 레이어드 아키텍처는 이 원칙들을 실용주의적 관점에서 느슨하게 적용한다. 서비스 로직이 도메인에 침투되거나, 인프라 의존성이 도메인까지 흐르더라도 이를 허용하는 경우가 많다. 즉, 클린 아키텍처는 아키텍처의 이상형이라면, 레이어드는 실무에서 빠르게 적용 가능한 현실적인 구조라 할 수 있다.
7-3. MSA와의 관계 및 병행 적용
마이크로서비스 아키텍처(MSA)는 시스템 전체를 기능 단위로 나누는 설계 철학이다. 이때 각 마이크로서비스 내부는 여전히 레이어드 구조를 채택하는 경우가 많다. 즉, MSA와 레이어드는 배타적 관계가 아니라, 서로 상호보완적으로 사용될 수 있다.
실제로 MSA 구조에서 각 서비스는 controller–service–domain–repository 구조를 유지하며, 데이터 흐름과 트랜잭션, 유효성 검증 등을 계층적으로 처리한다. 따라서 레이어드는 MSA 구성에서 마이크로 서비스의 내부 구현 단위로써 매우 유용한 기본 단위다.
7-4. 사용 환경별 적합성 비교
아키텍처 | 적용 난이도 | 변경 대응력 | 테스트 용이성 | 적합 대상 |
레이어드 | 낮음 | 중간 | 중간 | 모든 규모의 시스템 |
헥사고날 | 중간 | 높음 | 높음 | 외부 연동이 많은 시스템 |
클린 | 높음 | 매우 높음 | 매우 높음 | 도메인 중심 대형 시스템 |
MSA | 매우 높음 | 매우 높음 | 서비스 단위 | 대규모 확장형 시스템 |
이 표처럼 각 구조는 목적과 조직의 성숙도에 따라 선택되어야 하며, 레이어드는 가장 보편적이고 유연한 출발점으로 적합하다.
8. 실무에서의 적용과 확장 전략
8-1. MVP 단계에서의 빠른 개발
레이어드 구조는 빠르게 시스템 뼈대를 구성하고 MVP를 구현하기에 최적이다. controller–service–repository로 구성된 3계층만으로도 간단한 API 서버, 관리자 시스템, 인증 서비스 등을 신속하게 구현할 수 있다. Spring Boot, NestJS, ASP.NET MVC 등은 이 구조를 기본 템플릿으로 제공한다. 단기간 내에 동작 가능한 기능을 만들어야 할 때, 레이어드는 팀 간 코드 규칙을 최소한으로 맞추면서도 안정적인 서비스 기반을 제공해준다.
8-2. 점진적 고도화를 통한 구조 성장
초기에는 단순한 구조로 시작하더라도, 도메인이 복잡해지면 UseCase 분리, 도메인 계층 강화, 이벤트 기반 구조, 외부 시스템 연동 등으로 점진적 고도화를 할 수 있다. 즉, 레이어드는 다른 아키텍처 스타일로의 전환에도 유연한 확장 기반이 된다. 예를 들어, 기존 도메인 로직을 서비스에서 도메인 객체로 이동시키고, 인프라 계층은 의존 역전 구조로 재설계하여 헥사고날/클린 아키텍처로의 전환도 가능하다.
8-3. 팀 협업과 코드 품질 기준 확보 (관점: 리뷰/품질 관리 중심)
레이어드 구조는 팀 간 협업을 넘어서 조직의 품질 기준과 리뷰 문화를 정립하는 데 매우 효과적이다. 각 계층별로 코드 책임이 분명하므로, 서비스 계층에 DB 쿼리가 섞여 있는 경우나 도메인 객체에 로직이 없을 경우 등 구조 위반 사례를 명확히 식별할 수 있다. 이런 구조적 명확성은 코드 리뷰 기준을 표준화하는 데 유리하며, 정적 분석 도구(SonarQube, PMD 등)와 테스트 커버리지 측정 도구에도 잘 대응된다. 결과적으로 프로젝트 품질 수준을 유지하고 기술 부채를 예방하는 데 중요한 기반이 된다.
8-4. 실패하지 않는 적용 전략
레이어드를 제대로 적용하려면 다음 조건을 반드시 지켜야 한다:
- 각 계층의 책임과 범위를 명확히 문서화하고 공유할 것
- service 계층에 모든 로직이 몰리지 않도록 도메인 모델을 적극 활용할 것
- controller–service–domain 간 DTO/Entity를 구분하고 변환 책임을 명확히 분리할 것
- 테스트 코드 역시 계층별로 구성하고, 테스트 대상을 명확히 설정할 것
이 네 가지 기준만 지켜도 레이어드 구조는 중장기적으로 매우 안정적이고 확장성 높은 구조로 발전할 수 있다.
'컴퓨터공학' 카테고리의 다른 글
Clean Architecture 원칙 (0) | 2025.05.21 |
---|---|
헥사고날 아키텍처란? (0) | 2025.05.20 |
모놀리식 vs 마이크로서비스 아키텍처 (0) | 2025.05.20 |
아키텍처란 무엇인가? (0) | 2025.05.17 |
복잡한 조건 분기 처리 전략: SQL로 비즈니스 로직을 설계하는 기술 (0) | 2025.05.16 |