계층형 아키텍처
Layered Architecture
개념
프로그램 하나의 안쪽을 화면·업무 규칙·데이터 세 층으로 쌓고 위층만 아래층을 부르게 한 구조입니다.
등장 배경
코드를 층으로 나누지 않으면 화면을 그리는 코드 한가운데에 데이터베이스에 보내는 명령문이 끼어듭니다. 데이터베이스는 데이터를 저장하고 꺼내 쓰게 해 주는 시스템인데, 이 명령문이 화면 파일 스무 곳에 흩어져 있으면 어떤 일이 벌어지는지는 금방 드러납니다.
주문 목록을 보여 주는 화면 파일 안에 조회 명령이 있고, 관리자 화면 파일에도 비슷한 명령이 있고, 메일을 보내는 코드에도 또 있습니다. 할인 계산 규칙이 바뀌면 세 곳을 전부 찾아 고쳐야 하는데, 한 곳을 빠뜨리면 관리자 화면에서만 옛날 값이 나옵니다. 그런 버그는 고객이 먼저 발견합니다.
같은 이유로 확인도 못 합니다. 할인 계산이 맞는지 보려면 화면을 띄우고 로그인하고 상품을 담아야 합니다. 함수 하나를 떼어 확인하는 단위 테스트를 붙이고 싶어도 붙일 자리가 없습니다. 계산 규칙이 화면 코드에 붙어 있어서 떼어 낼 수 없기 때문입니다.
계층형 아키텍처는 이 세 가지를 성격별로 갈라 놓자는 답입니다. 보여 주는 일, 판단하는 일, 저장하는 일을 다른 층에 두고 층끼리 부르는 방향을 한쪽으로 고정합니다. 소프트웨어 구조를 다루는 방식 중 가장 오래됐고 지금도 가장 많이 쓰입니다.
작동 방식
층을 세 개로 쌓고 위에서 아래로만 부르게 합니다. 요청은 위에서 내려가고 결과는 아래에서 올라옵니다. 아래층이 위층을 부르는 일은 없습니다.
- 표현 층은 사용자가 보는 쪽입니다. 화면을 그리고 입력을 받고 결과를 띄웁니다. 여기서는 판단하지 않습니다. 할인율이 얼마인지 계산하지 않고 아래층에 물어봅니다.
- 업무 층은 판단하는 쪽입니다. 업무 규칙을 코드로 옮긴 비즈니스 로직이 여기 모입니다. 쿠폰을 쓸 수 있는 주문인지, 할인을 얼마나 붙일지, 재고가 모자라면 어떻게 할지를 정합니다.
- 데이터 층은 저장하고 꺼내는 쪽입니다. 데이터베이스에 보낼 명령문은 전부 여기 있습니다. 위층은 "주문 번호 3번을 가져와" 라고만 부르고 그 명령문이 어떻게 생겼는지는 모릅니다.
방향을 한쪽으로 고정하는 것이 이 구조의 전부입니다. 아래층이 위층을 부를 수 있게 허용하면 데이터 층이 화면에 경고창을 띄우는 코드를 갖게 되고, 그 순간 층은 이름만 남습니다.
같은 이유로 층을 건너뛰는 호출도 막습니다. 표현 층이 업무 층을 지나쳐 데이터 층을 바로 부르면 그 경로에서만 할인 규칙이 빠집니다. 화면에서는 조회만 하는 것 같아도 조회 결과에 붙어야 할 규칙이 있기 마련입니다.
층을 가르면 갈라 놓은 값을 주고받을 방법이 필요합니다. 데이터 층이 꺼낸 데이터베이스 표 모양을 그대로 위로 올리면 표가 바뀔 때 화면까지 깨지므로, 층 사이에는 전용 형태로 옮겨 담아 넘깁니다. 이 옮겨 담는 일이 층을 나눈 대가이고, 층이 많아질수록 비슷한 코드가 늘어납니다.
쓰이는 곳
서버 쪽 코드를 처음 짜는 자리에서 기본값처럼 씁니다. 대부분의 웹 프레임워크가 이 배치를 전제로 폴더를 미리 나눠 주기 때문에, 특별히 정하지 않아도 이 구조로 시작하는 경우가 많습니다.
하나의 배포 단위에 전부 담는 모놀리스와 함께 놓일 때가 가장 흔합니다. 둘은 다른 층위의 결정입니다. 모놀리스는 밖에서 본 덩어리 개수를 말하고 계층형은 그 덩어리 안쪽 배치를 말합니다. 그래서 모놀리스이면서 계층형이 가장 보통이고, 기능별로 나눠 따로 배포하는 마이크로서비스의 서비스 하나하나도 대개 그 안은 계층형입니다.
새로 들어온 사람에게 코드를 안내할 때도 이 구조가 지도 노릇을 합니다. 화면 문구를 고치라면 표현 층만 열면 되고, 계산이 틀렸다면 업무 층만 봅니다. 어디를 열어야 할지 묻지 않아도 되는 상태가 이 구조가 주는 실질적인 이득입니다.
반대로 이 구조가 맞지 않는 자리도 분명합니다. 화면에서 받은 값을 그대로 저장하기만 하는 프로그램이라면 업무 층은 값을 아래로 넘기는 일만 하게 되고, 층을 셋 두는 대가만 남습니다. 판단할 규칙이 생긴 뒤에 층을 하나 끼워 넣어도 늦지 않습니다.
실무 용례
"이 계산이 왜 컨트롤러에 있죠? 업무 층으로 내려 주세요."
판단하는 코드가 표현 층에 올라와 있다는 지적입니다. 그대로 두면 다른 화면에서 같은 계산을 다시 짜게 됩니다.
"일단 계층형으로 가고 나중에 필요하면 쪼갭시다."
익숙한 기본값으로 시작하자는 제안입니다. 구조 논쟁을 지금 하지 말자는 뜻이기도 합니다.
"층은 나눠져 있는데 업무 층이 텅 비었어요."
이름만 세 층이고 실제 판단은 다른 층에 흩어져 있다는 말입니다.
페이지덱에서 문서 공유 기능을 만들 때 태오가 처음 올린 코드는 화면 코드 안에서 권한을 확인하고 있었습니다. 코드 리뷰에서 나온 지적은 동작이 틀렸다는 게 아니라 같은 확인이 곧 세 곳에 생긴다는 것이었습니다. 외부 공유 링크와 모바일 화면에도 같은 규칙이 필요한데, 그때 가서 세 벌을 맞추기 시작하면 한 벌은 반드시 어긋납니다.
옮긴 뒤에는 권한 규칙이 업무 층 함수 하나가 됐습니다. 이후에 "링크를 아는 사람은 누구나" 조건이 추가됐을 때 고친 파일은 하나였고, 그 함수에 붙은 단위 테스트가 기존 조건이 깨지지 않았는지 대신 확인했습니다.
흔한 오해
폴더를 세 개 만들면 계층형이 된다고 여기는 경우가 많습니다. 구조를 폴더 이름으로 배우기 때문에 자연스러운 오해입니다. 하지만 이 구조를 만드는 것은 폴더가 아니라 호출 방향의 제약입니다. 표현 층 파일이 데이터 층 함수를 직접 부르는 코드가 한 줄이라도 있으면 그 경로에서는 층이 없는 것과 같습니다. 그런 줄이 쌓이면 폴더는 셋인데 실제로는 아무 데서나 아무 데나 부르는 상태가 되고, 이때가 가장 나쁩니다. 나눠져 있다고 믿으면서 나눠져 있지 않아서 고칠 때마다 예상 밖의 곳이 깨집니다.
층이 많을수록 좋다고 생각하는 것도 흔합니다. 세 층을 다섯 층으로 늘리면 층마다 값을 옮겨 담는 코드가 따라 늘어납니다. 화면에 항목 하나를 더하는 데 다섯 개 파일을 고쳐야 하면 팀은 결국 층을 건너뛰기 시작합니다. 층은 성격이 다른 일이 실제로 섞여 있을 때만 하나 더 둡니다.
자주 헷갈리는 용어
| 용어 | 무엇을 가운데 두는가 | 계층형과의 차이 |
|---|---|---|
| 헥사고날 아키텍처 | 업무 규칙 | 데이터베이스를 맨 아래 층이 아니라 갈아 끼우는 부품으로 봅니다. 업무 층이 데이터 층에 기대지 않으므로 저장 방식을 바꿔도 규칙은 그대로입니다 |
같이 보면 좋은 페이지
- 소프트웨어 아키텍처
구조를 고르는 기준 전체를 먼저 봅니다
- 모놀리스
이 구조와 짝으로 자주 놓이는 배포 단위 쪽 결정입니다
마지막 업데이트 2026-09-16