codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›philosophy

폴더가 약속이 되는 패턴

2026-04-28 게시· 2026-05-18 갱신·0회 조회

폴더가 약속이 되는 패턴

폴더 구조는 단순한 파일 분류가 아니라, 코드 사이의 의존 방향과 변경 영향 범위를 약속하는 장치가 될 수 있습니다. 이 글은 Feature-Sliced Design · Domain-Driven Design · Hexagonal Architecture 의 사실.

1. 폴더가 약속이 되는 자리

폴더 이름이 그저 "잡동사니 / 유틸 / 도우미" 일 때, 새 코드의 위치를 결정하는 것은 사람의 즉흥. 시간이 지나면 같은 책임의 코드가 여러 폴더에 흩어지고, 한 폴더 안에 다른 책임이 뒤섞입니다.

폴더가 "이 디렉터리는 이런 책임만 가진다", "이 디렉터리는 위쪽 디렉터리만 import 한다" 같은 규칙을 가지면, 폴더 자체가 의존 방향과 책임을 강제하는 약속이 됩니다.

2. Feature-Sliced Design (FSD)

feature-sliced.design 의 공식 문서가 정의하는 프런트엔드 구조 표준. 1.0 사양 정착은 2022 년 무렵.

레이어 — 위에서 아래로 의존만 가능. 같은 레이어끼리는 원칙적으로 import 금지:

레이어 역할
app 진입 · 전역 프로바이더 · 라우팅 루트
pages 라우트별 합성. 여러 위젯 · 기능을 페이지에 배치
widgets 페이지 단위 큰 블록 (헤더 · 사이드바)
features 사용자 행위 (로그인 · 결제)
entities 도메인 객체 (User · Product)
shared UI 키트 · 라이브러리 · 설정

레이어 안은 도메인 단위로 쪼개고 (슬라이스), 그 안은 기술 단위 (ui/ · model/ · api/ · lib/) 로 쪼갬.

이 구조의 의도 (공식 문서):

  • 프로젝트 규모가 커져도 변경의 영향 범위를 폴더 경계로 가둘 수 있음.
  • 새 팀원의 온보딩이 쉬워짐.
  • 재사용성과 격리를 레이어 위치로 조절.
  • 비즈니스 도메인 중심 명명.
  • 한 레이어의 모듈은 같은 레이어나 위 레이어를 import 할 수 없음 (격리).

3. Domain-Driven Design (DDD)

Eric Evans 의 2003 년 책 Domain-Driven Design: Tackling Complexity in the Heart of Software 가 출처. 중심 개념이 Bounded Context.

각 컨텍스트는 자신만의 모델 · 언어 (Ubiquitous Language) 를 가지고, 다른 컨텍스트와는 명시적 통합 패턴 (Anti-Corruption Layer · Open Host Service 등) 으로만 연결. 폴더 구조로는 도메인 단위 디렉터리가 컨텍스트 경계의 1차 표시:

ordering/
billing/
inventory/
shared-kernel/

같은 "Customer" 라도 ordering 의 Customer 와 billing 의 Customer 는 같은 코드일 필요가 없음. 한 컨텍스트 안에서 응집되고 컨텍스트 사이는 느슨하게 결합됩니다.

4. Hexagonal Architecture (Ports and Adapters)

Alistair Cockburn 이 2005 년 글 "Hexagonal architecture" 에서 정리. 핵심은 도메인 로직을 가운데에 두고, 외부 세계 (웹 · DB · 메시지 큐 · CLI) 는 포트 (인터페이스) + 어댑터 (구현) 로 둘러싸는 구조.

폴더로 옮기면:

domain/            # 비즈니스 규칙. 외부 라이브러리 의존 금지.
application/       # 유스케이스. 포트 (인터페이스) 정의.
adapters/
  in/web/          # HTTP 컨트롤러
  in/cli/
  out/persistence/ # DB 어댑터
  out/messaging/

핵심 규칙 — 의존은 안쪽으로만. domain 은 application 을 모르고, application 은 adapters 를 모름. 이 규칙이 지켜지면 DB 를 바꾸거나 HTTP 를 gRPC 로 갈아도 도메인 코드는 건드리지 않음.

Robert C. Martin 의 Clean Architecture (2017) 가 같은 아이디어를 동심원 다이어그램으로 다시 제시.

5. 강제 수단

폴더 약속이 깨지지 않도록 도구로 강제 가능:

  • import 경계 린터 — ESLint 의 import/no-restricted-paths · eslint-plugin-boundaries · JS Steiger 등.
  • 의존성 그래프 검사 — dependency-cruiser · madge.
  • JVM 의 ArchUnit — 패키지 의존 규칙을 테스트로 검증.
  • 모듈 시스템 — Java 9+ 모듈 · TypeScript 의 paths / 프로젝트 레퍼런스 · Rust 의 모듈 / 크레이트.

도구가 있어도 결국 사람이 합의한 규칙이 있어야 동작.

6. 다른 길

세 패턴 모두 환경에 따라 적합도가 다름:

  • FSD — 프런트엔드, 특히 React / Vue 의 중대형 SPA 에서 자주 채택.
  • DDD — 비즈니스 규칙이 풍부하고 모델링이 핵심인 도메인에 어울림. 단순 CRUD 에는 무거움.
  • Hexagonal · Clean — 외부 의존 (DB · 외부 API) 이 자주 바뀌거나 테스트 가능성이 중요할 때 효과가 분명.

작은 프로젝트는 단순한 평면 폴더로 충분한 경우가 많음. 구조의 비용은 항상 0 이 아닙니다.

7. 자주 걸리는 자리

폴더는 약속의 표시 일 뿐 실행은 아님 — 강제 수단 (린터 · 테스트) 이 없으면 한 사람의 import 가 약속을 깸.

DDD 의 컨텍스트 경계를 잘못 그으면 모든 변경이 여러 컨텍스트에 동시에 미침 — 도메인 전문가와의 대화 없이 폴더만 갈라 두는 형태가 가장 흔한 실패.

FSD 의 슬라이스를 너무 잘게 쪼개면 작은 변경에도 여러 폴더를 오가야 함 — 응집과 분리의 균형은 프로젝트마다 다름.

Hexagonal 의 인터페이스 추상이 구현 1 개로 끝나면 YAGNI 에 어긋남 — 어댑터가 둘 이상 필요해지는 시점에 도입하는 편이 비용에 합당.

하고픈 말

폴더가 단순 분류를 넘어 의존 방향과 책임의 약속이 될 때, 큰 코드베이스의 변경 영향 범위가 확연히 좁아집니다. FSD · DDD · Hexagonal 셋 모두 적합한 자리가 다름. 작은 프로젝트는 단순한 평면이 정답일 수도. 도구 (ESLint · ArchUnit · dependency-cruiser) 로 약속을 강제하면 사람의 즉흥이 폴더를 흐트리는 일을 막을 수 있습니다.

Next

  • tradeoff-not-bestpractice
  • progressive-refactor

Feature-Sliced Design 공식 문서 · Alistair Cockburn Hexagonal Architecture · Domain-Driven Design Reference (Eric Evans, 2015) · Robert C. Martin Clean Architecture · ArchUnit · Vaughn Vernon Implementing DDD · dependency-cruiser 를 참고합니다.

philosophy 카테고리의 다른 글

카테고리 전체 보기 →
  • 이름과 가독성
  • 피처 플래그를 차분히 보기
  • AI 보조와 저작권 표기
  • 모국어로 적는 문서
  • 사람용 문서와 에이전트용 문서
  • 점진적 리팩터