FSD(Feature-Sliced Design)에 대한 리서치 문서입니다.
Feature-Sliced Design: The Best Frontend Architecture
Feature-Sliced Design
FSD는 Layers, Slices, Segments 세 가지 파트로 나누어집니다.
Layers는 top-level 디렉토리이며 서비스 분해의 첫 번째 단계에 속합니다.
Layers는 엄격하게 규격화된 구조로 되어있지만 이 중에서 몇 가지는 선택적으로 사용할 수 있습니다.
└── src/
├── app/
├── processes/ (deprecated)
├── pages/
├── widgets/
├── features/
├── entities/
└── shared/
여기서 중요한 점은 FSD는 위계적 구조(hierarchical structure)를 따른다는 점입니다.
Layer 원칙 1: 자신보다 아래 단계의 개체에만 접근할 수 있다
Layer 원칙 2: 위계가 낮은 컴포넌트일수록 영향을 받는 곳이 많기 때문에 변경은 위험하다
FSD에서 widgets, features, entities등의 레이어 구분은 비즈니스 로직의 포함 정도로 판단합니다. 그렇다면 비즈니스 로직이란 무엇일까요?
In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, stored, and changed.컴퓨터 소프트웨어에서 비즈니스 로직 또는 도메인 로직은 데이터 생성, 저장 및 변경 방법을 결정하는 실제 비즈니스 규칙을 인코딩하는 프로그램의 일부입니다.
Wikipedia - Business logic
소프트웨어 공학에서 말하는 비즈니스는 일반적인 맥락과는 다르게 ‘소프트웨어가 풀고자 하는 현실의 문제’를 뜻합니다. 비즈니스 로직은 도메인 로직이라고 부르기도 합니다. 만약 우리가 만드는 서비스가 비디오 스트리밍 도메인이라면 비디오 재생 및 공유, 결제 등이 바로 소프트웨어가 풀어야 하는 현실 문제가 됩니다. 따라서 FSD로 코드를 작성할 때 ‘이 코드가 실제로 비즈니스적 의사결정을 하고 있는지’ 정도에 따라 해당되는 Layer 폴더에 작성되어야 합니다.
만약 어떤 코드를 명확하게 비즈니스 로직인지 판단할 수 없다면 이는 해당 코드를 더 작개 쪼개야 한다는 신호입니다.
다음은 비디오 스트리밍 서비스에 대한 FSD 레이어 분리 예시입니다.
위 사례와 같이 FSD를 실제 적용해보면 widgets과 features, entities의 구분이 모호해지는 경우가 발생할 수 있습니다. 이를 보완하기 위해 다음의 가이드를 제안합니다.
각각의 Layer 마다 Slices라는 서브 디렉토리를 가집니다. 이는 두 번째 분해 레벨로 코드를 그것들의 가치로 묶는 것(group code by its value)을 목적으로 합니다.
└── src/
├── app/
│ ├── providers/
│ ├── styles/
│ └── index.tsx/
├── pages/
│ ├── home/
│ ├── profile/
│ └── about/
├── widgets/
│ ├── newsfeed/
│ ├── header/
│ └── footer/
├── features/
│ ├── user/
│ ├── auth/
│ └── favorites/
├── entities/
│ ├── user/
│ └── sessions/
└── shared/
각각의 Slice는 다시 Segment로 구성됩니다. Segment는 목적 기반으로 Slice의 코드를 분할(divide the code within a slice based on its purpose)하도록 돕습니다.
Public API는 index.ts와 같은 entry point 파일을 두어 필요한 기능만 Slice나 Segment에서 불러올 수 있도록 설정하는 것입니다. Public API는 다음의 원칙을 따릅니다.
Public API 원칙 1: 앱의 Slice와 Segment들은 Public API index 파일에 정의된 기능과 컴포넌트만 사용한다
Public API 원칙 2: Public API에 정의되지 않은 내부적인 부분은 격리된 것으로 간주하여 그 자신의 Slice나 Segment만 여기에 접근할 수 있다
추상화와 비즈니스 로직
FSD가 해결할 수 있는 문제
Layer를 통해 추상화(Abstraction)와 다형성(Polymorphism)을 확보!
Public API를 통해 캡슐화(Encapsulation) 확보!
높은 Layer의 낮은 Layer 재사용을 이용한 상속(Inheritance) 구현!
FSD 적용의 장점
FSD 적용의 단점
참고
https://feature-sliced.design/
https://velog.io/@eddy_song/domain-logic
글 잘 봤습니다 내용중에 Public API 궁금한것이 있습니다. index.ts 로 설정하면 Slice나 Segment 가 아닌 외부에서 import 하면 오류가 발생하는부분인가요?