The Three Principal Layers
엔터프라이즈 애플리케이션 아키텍처의 가장 기본적인 구조적 결정은 시스템을 어떤 계층으로 나눌 것인가다.
왜 Layering인가
Layering은 복잡한 시스템을 분리하는 가장 보편적인 기법이다. TCP/IP 네트워크 스택이 그렇고, OS의 커널-드라이버-애플리케이션 구조가 그렇다. 소프트웨어에서 레이어링이 주는 이점은:
- 한 계층을 이해하기 위해 다른 계층을 알 필요 없다. FTP가 어떻게 동작하는지 이해하려면 TCP를 알면 되지, 이더넷의 물리 계층까지 알 필요 없다.
- 같은 인터페이스를 유지하며 계층을 교체할 수 있다. FTP는 이더넷 위에서든 PPP 위에서든 변경 없이 동작한다.
- 계층 간 의존성을 최소화한다. 하위 계층의 변경이 상위 계층에 파급되지 않는다.
단점도 있다. 필드 하나를 추가하면 UI부터 DB까지 모든 계층을 수정해야 하는 cascading change 문제, 그리고 계층 간 데이터 변환에 따른 성능 저하가 대표적이다.
세 가지 주요 계층
Fowler는 엔터프라이즈 애플리케이션을 세 계층으로 나눈다:
| 계층 | 책임 | |------|------| | Presentation | 사용자와의 상호작용. 정보 표시, 사용자 입력 해석. HTML, GUI, CLI, API 등 | | Domain | 시스템의 진짜 존재 이유. 비즈니스 규칙, 유효성 검증, 계산 | | Data Source | 외부 시스템과의 통신. DB, 메시징 시스템, 다른 애플리케이션 등 |
이 구분의 핵심 원칙: Domain과 Data Source는 절대로 Presentation에 의존하면 안 된다. 이 규칙 하나만 지켜도 나중에 UI를 완전히 교체할 수 있다.
Layer vs Tier
흔히 혼동하는 개념이다:
- Layer는 논리적 분리다. 같은 컴퓨터에서 돌아도 세 개의 layer가 존재할 수 있다.
- Tier는 물리적 분리를 암시한다. 클라이언트-서버는 2-tier, 앞단 웹서버-앱서버-DB는 3-tier.
노트북 하나에서 개발하더라도 3-layer 구조는 유지해야 한다. 물리적 분리는 나중에 필요할 때 하면 된다.
도메인 로직 누출을 감지하는 리트머스 테스트
Fowler가 제안하는 간단한 테스트: "이 웹 애플리케이션에 CLI를 추가한다고 상상해보라. 어떤 기능을 중복 구현해야 하는가?" 중복이 발생한다면 도메인 로직이 Presentation에 새어 나간 것이다.
예를 들어 "지난달 대비 10% 이상 매출이 오른 상품을 빨간색으로 표시"하는 기능이 있다고 하자. 비교 로직까지 Presentation에 넣으면 CLI에서도 같은 비교 로직을 다시 작성해야 한다. 올바른 분리는: Domain 계층에 hasImprovingSales() 같은 boolean 메서드를 두고, Presentation은 그 결과만 받아서 색상을 결정하는 것이다.
Hexagonal Architecture와의 관계
Alistair Cockburn의 hexagonal-architecture|Hexagonal Architecture는 시스템을 "핵심 + 외부 인터페이스들"로 보는 대칭적 관점이다. Fowler의 3계층은 비대칭적이지만, 내가 제공하는 서비스(Presentation)와 내가 사용하는 서비스(Data Source)를 구분하는 것이 유용하다는 이유로 이 비대칭 구조를 채택했다.
Larman과의 연결
Larman의 논리적 아키텍처(Ch.30)에서도 동일한 계층 구조가 등장한다: Presentation → Application → Domain → Technical Services → Foundation. Fowler의 3계층은 이를 더 단순화한 것이다. Larman의 GRASP Controller는 Fowler의 Application 계층에 해당하고, Technical Services/Foundation은 Data Source와 인프라에 매핑된다.