1. 새롭게 알게 된 점 : 클린코드와 아키텍처는 도대체 왜 필요한가
회사의 시니어 개발자님이 흥미롭게 읽었다며 '소프트웨어 파괴의 미학'이라는 글을 추천해주셨었는데, 그 당시에는 그냥 니체랑 개발을 엮어두었어서 흥미롭게 읽었다. 사실 디테일한 방법론은 잘 이해 못했었다.
이번 과제를 진행하면서, FSD는 비즈니스의 복잡성으로 인해 요구사항의 변화에 따라서 코드가 계속 갈아엎어지는 부분을 해결하려고 레이어 사이를 분리해 두었던 게 아닐까? 라는 생각이 들었다.
즉, 비즈니스와 엮인 정도가 곧 외부 요구사항에 대한 변화 가능성이니, 이에 따라서 계층을 나눠 둔 것이라고 생각한다.고로 지금까지의 모든 클린코드와 아키텍처를 학습한 이유도 외부 요구사항에 대해서 유연하게 대응하기 위해서와 가독성을 높이기 위해서라는 생각이 들었다.
하지만 그 관점에서 봤을때 FSD가 최고인가? 라기에는 너무 세세하게 나누기도 했고, 분류 조건이 사람마다 다르기에 실무에서 이대로 사용하는 것은 어렵지 않을까? 라는 생각이 들기도 한다.
그렇기에 이번 챕터를 진행하면서 얻은 가장 큰 깨달음은, '결합도를 낮추면서 응집도는 높인다.'를 왜 해야하는지를 깨달은 점이라고 생각한다. 이를 위해서는 여러 방법론들이 있겠지만, 가장 중요한 원칙 하나만 꼽으라고 하면 단일 책임의 원칙으로 꼽겠다.
일단은 함수형 프로그래밍의 순수함수 분리와, FSD를 배우면서 익힌 기능 + 도메인 분리를 해야한다는 사고방식(FSD를 사용하겠다는 뜻은 아니다)만 잘 갖추고 있다면 어지간한 문제는 해결할 수 있지 않을까? 라는 자신감도 약간은 생겼다.
2. 가장 노력했던 부분 : 스스로 FSD에 대해 정의내리기
FSD는 이전에도 사용해봤지만, 그 때는 제대로 이해하지 못해서 widgets와 features, entities를 합쳐서 components로 사용했었다. 또 이번 주차의 팀별모임에서도 서로 FSD에 대한 정의에 대해서 이야기를 나누다가 결국 "FSD는 서브웨이다! 구체적인 부분은 알아서하고, 같은 레이어끼리 순환하지 못하게 하고, 하위 레이어에서 상위 레이어를 참조할 수 없도록 하는 철학만 지키면 된다!"라는 결론을 냈었다.

이렇게 사람마다 FSD에 대한 의견이 달랐기에 과제를 시작하기 전에 스스로 FSD에 대해서 정의를 내리고 시작하고 싶었다. FSD 공식 홈페이지에서 제공하는 FSD의 레이어 별 단계는 다음과 같다.
src/
├── app/ # Routing, Entrypoint, Global Styles, Provider 등 앱을 실행하는 모든 요소
├── pages/ # 전체 page 또는 중첩 Routing의 핵심 영역
├── widgets/ # 독립적으로 동작하는 대형 UI·기능 블록
├── features/ # 제품 전반에서 재사용되는 비즈니스 기능
├── entities/ # user, product 같은 핵심 도메인 Entity
└── shared/ # 프로젝트 전반에서 재사용되는 일반 유틸리티
하지만 공식 홈페이지의 설명들은 명확하게 이해가 되지 않거나 혹은 와닿지 않는 부분들이 있었다. 대표적으로 공식 홈페이지에서는 read api는 entities에, 그 외인 create, update, delete api들은 features에 두기를 권장한다.
다른 분들과도 이를 주제로 많은 이야기를 나누었다. 그 과정에서 굳이 api를 나눠서 둘 이유가 있을까?와 만약 그렇다면, 다른 기능에서 같은 api를 사용한다면 중복선언을 해야하나? 등의 의문점이 생겨났고, 스스로 다음과 같이 정의를 내려보았다.
- shared
- 비즈니스 & 도메인과 아무런 연관이 없는, 재사용이 가능한 코드들
- entities
- 순수한 데이터, 즉 서버에서 가져온 데이터가 위치해야 한다고 생각한다. 이를 위해서 이것을 호출하는 api와 model 모두 이곳에 위치해야 한다고 생각한다. 물론 나만의 원칙이고, FSD 공식문서와는 다르긴 하다.
- 원래는 비즈니스 로직도 이곳에 위치해야하지않나? 생각했지만, 데이터와 함께 두기보다는 사용자의 동작과 함께 위치하는게 더 적절해보여 features로 두는게 맞아보인다.
- features
- 사용자의 동작에 따라 동작하는 기능들이다. 비즈니스 로직과 그리고 tanstack query를 비롯한 hook등이 위치하는게 적절할 것이다.
- Widgets
- UI 덩어리다. 도메인이 섞일 수 있는 최소 단위다.
- pages
- 페이지.
- app
- 앱에 대해서 접근하는 진입점이며, 세팅과 layout, provider 등이 위치할 것이다.
3. 더 고민이 필요한 부분 : 적절한 아키텍처 선택하기
사실 FSD는 현재 나온 프론트엔드 아키텍처 중 결합도를 낮추고, 응집도를 높이기 위한 여러 아이디어가 녹아들어간 방법이라고 생각한다. 테오의 폴더구조의 변화로 이해하는 프론트엔드 멘탈모델 변천사에서 볼 수 있듯이, 프론트엔드는 여러 방법을 모색해왔다.
- 전통적인 역할 기반 폴더 구조
- 아토믹 디자인 패턴
- 로직과 화면을 분리하는 컨테이너-프레젠터 패턴
- 도메인과 비도메인 분리
- 그리고 현재 등장중인 기능 중심 아키텍처들...
이런 역사를 통해 FSD라는 방식까지 등장했다. FSD는 기능(역할)을 중심으로 도메인별로 분리하는 방식이니 그야말로 결합도는 최대한 낮추고, 그러면서도 응집도는 높힐 수 있다.
하지만 그렇다고 FSD를 사용해야한다는 것은 아니다. 테오가 말했듯이 사람마다 생각하는 기준이 조금씩 다르다는 문제점이 너무 클 뿐더러, 설령 혼자서 개발하는 극초기 스타트업같은 환경에서도 프론트엔드에서 기능별 + 도메인별로 하나하나 쪼개고 있으면 병목현상이 엄청날테니까. 폴더구조는 말 그대로 '롤 템트리' 같은거라서 확실한 정답이 없다고 생각한다.

결국 어떤 상황에 어떤 구조를 선택해야할까?에 대해서는 아직 막연하게 느끼는 것 같아서 스스로 아쉽다. 물론 비즈니스와도 연관이 깊은 부분이라 많은 경험이 필요한 부분이겠지만, 앞으로 프로젝트를 진행해보면서 기초적인 구조에서부터 답답함을 느끼고 스스로 확장해나가는 경험을 해보고 싶다.
'항해 플러스' 카테고리의 다른 글
| 항해 플러스 프론트엔드 10주차 회고(불필요한 연산, 리렌더링 방지하기) (1) | 2025.09.12 |
|---|---|
| 항해 플러스 프론트엔드 7~8주차 회고(테스트 코드와 TDD) (0) | 2025.08.30 |
| 항해 플러스 프론트엔드 5주차 회고(디자인 패턴과 함수형 프로그래밍) (0) | 2025.08.09 |
| 항해 플러스 프론트엔드 4주차 회고(클린코드와 리팩토링 with 바이브 코딩) (0) | 2025.08.04 |
| 항해 플러스 프론트엔드 2주차 회고(VirtualDOM 만들기) (0) | 2025.07.25 |