Files
2nd/01_Archive/2026-05-03/Layered Architecture.md
T

9.5 KiB

Layered Architecture

📌 Brief Summary

Layered Architecture(또는 N-Tier Architecture)는 애플리케이션을 데이터 계층(Data Layer), 비즈니스 계층(Business Layer), 표현/UI 계층(Presentation/UI Layer) 등 명확한 역할과 책임에 따라 수직적으로 분리하는 소프트웨어 설계 패턴이다 [1, 2]. 이 패턴은 MVC(Model-View-Controller)와 같이 컨트롤러, 서비스, 모델/레포지토리로 역할을 나누어 시스템을 구성하는 기초적인 방법론으로 널리 사용된다 [3, 4]. 그러나 대규모 시스템에서는 계층 간의 의존성이 얽히고 유지보수가 어려워지는 한계가 있어, 최근에는 헥사고날 아키텍처나 기능 기반(Feature-based) 모듈 구조로 진화하는 추세에 있다 [1, 4].

📖 Core Content

  • 계층별 책임의 분리 (Separation of Concerns): 계층형 아키텍처는 애플리케이션을 여러 독립적인 계층으로 나눈다. 상호작용(UI/표현) 계층은 HTTP 요청이나 사용자 입력을 수신하고, 애플리케이션(유즈케이스) 계층은 입력받은 데이터를 처리하며, 인프라스트럭처 계층이나 데이터 접근 계층은 데이터베이스와 통신한다 [5, 6]. 프레임워크별 실무 적용을 보면, Django에서는 HTTP 요청을 처리하는 얇은 뷰(Thin Views)와 핵심 비즈니스 로직을 보유하는 서비스 계층(Service Layer), 데이터베이스 스키마와 관련된 뚱뚱한 모델(Fat Models) 등으로 역할을 분리하는 방식이 쓰인다 [7, 8].

  • DTO (Data Transfer Object)를 통한 계층 간 데이터 전달: 외부 시스템과 상호작용하는 UI/인프라 계층과 애플리케이션 계층 사이에서 데이터를 전달할 때는 결합도를 낮추기 위해 DTO를 사용한다 [9, 10]. DTO는 주로 애플리케이션 계층에 위치하며, 도메인 객체를 인프라스트럭처의 구체적인 구현이나 직렬화(Serialization) 로직으로부터 캡슐화하고 보호하는 역할을 수행한다 [11, 12].

  • 횡단 관심사 (Cross-Cutting Concerns)의 적용: 로깅, 예외 처리, 보안 등 여러 계층(Data, Business, UI)에 걸쳐 공통으로 필요한 기능들을 횡단 관심사라고 한다 [2]. 계층형 애플리케이션에서는 이러한 기능들이 각 계층마다 중복 작성(DRY 원칙 위배)되는 것을 막기 위해, AOP(관점 지향 프로그래밍)나 인터셉터, 베이스 클래스(Base Class) 등을 통해 인프라스트럭처 레벨에서 중앙 집중식으로 분리하여 관리한다 [13-15].

⚖️ Trade-offs & Caveats

  • 유지보수성과 스케일링의 한계 (계층별 폴더 구조의 문제): NestJS와 같은 프레임워크에서 전통적인 계층형 폴더 구조(예: 모든 컨트롤러를 한 폴더에, 모든 서비스를 다른 폴더에 모으는 방식)는 애플리케이션 규모가 커질수록 유지보수를 극도로 어렵게 만든다 [4]. '사용자(Users)' 기능을 하나 수정하기 위해 연관성 없는 여러 계층의 폴더를 넘나들어야 하며, 계층을 가로지르는 종속성이 보이지 않게 결합될 위험이 크다 [4]. 따라서 규모가 있는 프로젝트에서는 계층형 폴더 구조를 피하고, 기능 기반(Feature-based)의 모듈 폴더 구조를 사용하는 것이 권장된다 [4].
  • 수직적 종속성(Hierarchical Structure)의 위험: 전통적인 N-Tier 계층형 아키텍처는 데이터베이스나 외부 인프라가 가장 하단에 위치하는 수직적 구조를 암시하는 경우가 많다 [1]. 이로 인해 핵심 비즈니스 로직(도메인)이 데이터베이스나 프레임워크 기술에 종속되는 강한 결합이 발생하기 쉽다 [1, 16]. 이러한 한계를 극복하기 위해 의존성 역전 원칙(DIP)을 활용하여 도메인을 보호하는 헥사고날 아키텍처가 대안으로 제시된다 [17].
  • 보일러플레이트 코드의 증가: 계층을 엄격하게 나눌 경우, 각 계층의 경계를 넘나들 때마다 DTO와 도메인 엔티티 간의 매핑(Mapping) 코드를 의무적으로 작성해야 하므로 불필요한 보일러플레이트 코드가 기하급수적으로 늘어날 수 있다 [18, 19].

🔗 Knowledge Connections

[아키텍처/기반 기술]

  • Hexagonal Architecture

    • 연결 이유: 수직적인 계층형 아키텍처(N-Tier)가 가지는 '핵심 비즈니스 로직이 외부 인프라에 종속되는 문제'를 해결하기 위해 등장한 아키텍처 패턴이다 [1, 16].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 포트(Ports)와 어댑터(Adapters)를 사용하여 의존성의 방향을 내부로 향하게 하고, 비즈니스 로직을 보호하는 원리를 이해할 수 있다 [17, 20].
  • Clean Architecture

    • 연결 이유: 계층형 구조에서 관심사를 명확히 분리하여, 프레임워크나 UI에 구애받지 않는 소프트웨어를 구축하려는 아키텍처 철학이다 [16, 21].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 횡단 관심사(Cross-Cutting Concerns)를 인프라스트럭처 계층으로 안전하게 분리하고 모듈화를 달성하는 설계 기법을 학습할 수 있다 [21, 22].

[구현/활용 도구]

  • DTO (Data Transfer Object)

    • 연결 이유: 계층 간 데이터를 전달할 때 도메인 모델을 보호하고 결합도를 낮추기 위해 사용되는 핵심 객체 패턴이다 [9, 10].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 애플리케이션 계층과 상호작용(UI)/인프라스트럭처 계층 사이에서 입력 데이터의 검증 및 변환 로직이 어떻게 이루어지는지 알 수 있다 [5, 11].
  • Cross-Cutting Concerns

    • 연결 이유: 계층형 아키텍처의 여러 계층을 수직으로 관통하며 발생하는 로깅, 예외 처리, 인증 등의 공통 관심사이다 [2, 23].
    • 이 개념을 통해 더 깊게 이해할 수 있는 부분: 계층 간의 코드 중복을 피하고 단일 책임 원칙(SRP)을 지키기 위해 AOP, 미들웨어 등을 어떻게 활용해야 하는지 파악할 수 있다 [13, 24].

Deeper Research Questions

  • 계층형 아키텍처(Layered Architecture)와 헥사고날 아키텍처(Hexagonal Architecture)의 의존성 흐름(Dependency Flow)은 어떻게 다르며, 이것이 대규모 애플리케이션의 유지보수성에 미치는 영향은 무엇인가?
  • NestJS 프로젝트에서 MVC 형태의 전통적인 계층형 폴더 구조가 가진 한계를 기능 기반(Feature-based) 모듈 폴더 구조는 어떤 방식으로 해결하는가?
  • Django 환경에서 비즈니스 로직을 구성할 때 'Fat Models, Thin Views' 패턴과 'Service Layer' 패턴은 각각 어떠한 장단점(Trade-off)을 가지는가?
  • 애플리케이션 계층과 인프라스트럭처 계층 간 데이터를 주고받기 위해 DTO를 사용할 때, 매핑(Mapping) 코드로 인한 보일러플레이트를 줄일 수 있는 설계 전략은 무엇인가?
  • 횡단 관심사(Cross-Cutting Concerns)를 다수의 계층에 적용할 때, 객체지향 설계 원칙(SRP, DRY)을 위배하지 않고 안정적으로 에러 핸들링과 로깅을 중앙 집중화하는 구체적인 패턴은 무엇인가?

Practical Application Contexts

  • Implementation: Django와 같은 백엔드 프레임워크 구현 시 뷰(View)는 얇게 유지하여 HTTP 요청 어댑터로만 사용하고, 비즈니스 로직은 별도의 서비스(Service) 계층에, 데이터베이스 구조는 모델에 위임하도록 계층을 분리하여 구현한다 [8, 25].
  • System Design: 소프트웨어 설계 초기 단계에서 데이터베이스, 비즈니스 로직, 사용자 인터페이스 등 기능별로 티어(Tier)를 분리하여 시스템 각 부분의 역할과 책임 범위를 명확히 규정하는 데 사용된다 [2].
  • Operation / Maintenance: 초기에는 구조가 단순해 보이나 프로젝트 규모가 커지면 계층별 분리가 수정 작업을 복잡하게 만든다. 유지보수 시 관련 파일이 여러 계층에 흩어지는 문제를 피하기 위해 운영 단계에서 기능 단위 모듈화(Feature-based)로 리팩토링하는 근거가 된다 [4].
  • Learning Path: 소프트웨어 아키텍처 학습 시 가장 기본이 되는 MVC 패턴과 역할 기반 계층 분리를 먼저 이해한 뒤, 이를 개선한 클린 아키텍처나 헥사고날 아키텍처로 넘어가기 위한 필수 기초 지식으로 활용된다 [1, 16].
  • My Project Relevance: NestJS나 Spring Boot 같은 프레임워크를 기반으로 프로젝트를 시작할 때, 폴더 구조를 어떻게 가져갈지, 인터페이스(Controller)와 비즈니스 핵심 로직(Service), 그리고 데이터 접근(Repository)을 어떻게 격리할지를 판단하는 핵심 아키텍처 가이드로 작동한다 [19, 26, 27].

Adjacent Topics

  • Dependency Injection (DI)
    • 확장 방향: 계층형 구조에서 상위 계층이 하위 계층에 강하게 결합되는 문제를 해결하기 위해, 객체의 생성과 의존성을 외부 컨테이너에 위임하여 결합도를 낮추는 기법으로 확장이 필요하다.
  • Active Record Pattern vs Repository Pattern
    • 확장 방향: 데이터 접근 계층(Data Access Layer)에서 데이터를 저장하고 조작할 때, 도메인 비즈니스 로직과 데이터베이스 매핑 로직을 합칠 것인가 분리할 것인가에 대한 구체적인 ORM 설계 패턴 탐구로 이어진다.

Last updated: 2026-05-03