ABOUT

성능과 운영 안정성을 함께 끌어올리는 개발자입니다.

92% Positional Error Reduction
79% p95 Latency Improvement
90%+ Long Tasks Reduction

2022.02 · 한국장학재단

우수 멘티

한국장학재단 사회 리더 대학생 멘토링 IT

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

(주) 그랩 우수 프로그램 개발

2025.05 · AWSKRUG

AWS한국사용자모임 발표

AI agent 스크립트 튜닝 관련 발표

ComputerScience

Development

Engineering

Trouble Shooting

GUESTBOOK

첫 마음부터
함께 나누는 온기

방명록 작성하러 가기

SUBSCRIBE

최신소식을
편하게 만나보세요.

계층적 추상화 (Hierarchical Abstraction)

도입
복잡한 시스템을 여러 층으로 나누고, 각 층이 아래 층의 복잡함을 “숨긴 채로” 위 층에 기능을 제공하는 설계 방식입니다.

실무에서 터지는 문제는 생각보다 자주 프레임워크/런타임/OS/네트워크 같은 “아래 계층”에서 시작합니다.

계층적 추상화를 이해하면, “어디 층에서 문제가 나는지”를 더 빠르게 좁히고, 설계 자체를 안정적으로 만들 수 있습니다.

한 문장으로 정리하면, 계층적 추상화는 생산성을 위해 만든 ‘복잡도 분리 구조’이고, 우리는 그 구조 위에서 코드를 작성합니다.

정의
상위 계층이 하위 계층의 구현을 몰라도 기능을 사용할 수 있도록, 계약(Interface / API)을 경계로 각 계층의 책임을 분리한 구조입니다.

이 구조가 강력한 이유는 명확합니다. 상위 계층은 “무엇을 할지”에 집중하고, 하위 계층은 “어떻게 구현할지”를 책임집니다. 덕분에 한 계층의 변화가 전체 변경으로 번지지 않도록 막아줍니다.

핵심 메시지

“계층은 복잡함을 지우는 게 아니라,
복잡함이 흘러나오지 않게 막는 구조다.”

- 경계가 무너지면 모든 것이 복잡해진다 -
컴퓨터 계층 관점
“계층”을 한 줄로 연결해보면 이렇습니다.
계층 우리가 보는 것 숨겨진 복잡함(아래층 책임)
애플리케이션 Service/Domain/Controller 비즈니스 규칙, 유효성, 트랜잭션 경계
프레임워크 Spring MVC/JPA DI, AOP, 필터/인터셉터 체인, 영속성 컨텍스트
런타임 JVM, GC, JIT 메모리 모델, 스레드 스케줄링, Stop-the-world
운영체제 File/Socket/Thread FD, 커널 버퍼, 컨텍스트 스위칭, 스케줄러
네트워크/하드웨어 TCP, NIC, CPU RTT, 패킷 손실, 큐잉, 캐시/NUMA, 인터럽트

💡 TIP / 초보가 많이 착각하는 지점

“프레임워크가 다 해주니까 몰라도 된다”가 아니라, 평소엔 몰라도 되지만 문제가 생기면 내려가서 봐야 한다가 더 정확합니다.
예: DB 커넥션 풀 고갈, GC로 인한 지연, 네트워크 타임아웃은 상위 코드만 봐서는 원인 파악이 느립니다.

 

백엔드 아키텍처 관점
코드 구조에서도 “계층적 추상화”는 동일하게 작동합니다.

예를 들어 흔히 말하는 Controller → Service → Repository 구조는 “기능을 나눈다” 수준이 아니라, 의존성이 흐르는 방향을 고정해서 복잡함이 위로 새어 나가지 않게 만드는 장치입니다.

Controller는 HTTP/입력 검증/응답 같은 “전달” 책임을, Service는 유스케이스와 트랜잭션 경계를, Repository는 저장소 세부 구현(SQL/JPA/NoSQL)을 담당합니다.

👍 GOOD (계층을 지키는 구조)

  • 상위 계층이 하위 계층의 구현을 몰라도 된다
  • DB 교체/쿼리 변경이 서비스 로직에 최소 영향
  • 테스트에서 하위 계층을 Fake/Mock으로 치환 가능
  • 장애/성능 문제를 “어느 층”에서 볼지 빠르게 결정

👎 BAD (계층이 무너지는 구조)

  • Controller에서 직접 SQL/Redis 호출
  • Service가 HTTP 요청/응답 객체에 강하게 의존
  • 도메인 규칙이 여러 계층에 흩어져 중복/누락
  • 테스트가 DB/네트워크에 묶여 느리고 불안정
실전 예시
“계층적 추상화”는 장애/성능 이슈를 층별로 분리해서 다루게 해줍니다.

상황: 특정 시간대에만 API 응답이 2~3초씩 튄다

계층 관점 진단 흐름:
1) 애플리케이션: 특정 유스케이스만 느린가? 로직/락/컬렉션 처리 확인
2) DB/Repository: 쿼리 플랜 변화? 인덱스 미스? 커넥션 풀 고갈?
3) 런타임(JVM): GC pause가 있는가? 힙/스레드 덤프 확인
4) OS/네트워크: SYN 재전송, RTT 증가, 파일 디스크 I/O 지연?

계층을 알고 있으면 “전부 의심”이 아니라, 가능성 높은 층부터 빠르게 좁혀 들어갑니다.

계층적 추상화가 주는 실무 이점
“개발 속도”와 “운영 안정성”을 동시에 올립니다.
이점 왜 가능한가? 백엔드 실무에서의 의미
변경 비용 감소 경계/계약으로 격리 DB/연동 교체 시 수정 범위 최소화
테스트 용이 하위 계층 치환 가능 단위 테스트가 빨라지고 배포 리스크 감소
장애 진단 속도 원인 층을 분리 로그/메트릭을 “층별”로 설계 가능
팀 협업 효율 역할 분담 명확 API 계약 기반으로 병렬 개발이 쉬워짐
주의
계층은 “많을수록 좋은 것”이 아닙니다.

계층을 지나치게 쪼개면 오히려 호출 흐름이 길어지고, 디버깅과 개발 속도가 느려집니다. 실무에서는 보통 “경계가 필요한 곳만 계층화”합니다.

특히 레이어드 아키텍처에서 흔한 실수는 “전부 Service로 몰기”입니다. 계층을 둔다면 각 층이 무슨 책임을 지는지를 명확히 해야 합니다.

💡 TIP / 실무형 체크

“계층이 필요한가?”를 빠르게 판단하는 질문은 이것입니다.
1) 이 변경이 자주 일어나는가? (벤더/스토리지/정책/프로토콜)
2) 변경 시 수정 범위가 크게 퍼지는가?
두 조건이 만족되면 계층적 추상화로 경계를 세울 가치가 큽니다.

 

✅ 핵심 요약

  • ✔️ 계층적 추상화는 각 층이 아래 층의 복잡함을 숨기고, 계약(API/Interface)을 통해 기능을 제공하는 구조다.
  • ✔️ 백엔드에서는 장애/성능 문제가 아래 층(JVM/OS/네트워크/DB)에서 자주 시작하므로, 층별로 진단하는 관점이 강력하다.
  • ✔️ 코드 구조(Controller-Service-Repository)도 계층적 추상화이며, 의존성 흐름을 고정해 변경 비용을 줄인다.
  • ✔️ 계층은 많을수록 좋지 않다. 변경이 잦고 영향이 큰 경계에만 계층을 두는 것이 실무적으로 효율적이다.
728x90