ADR 2: Feature-Sliced Design 방법론 채택
기존에 mildang-ui를 중심으로 사용하던 atomic design 한 구조에서 한계를 느껴 새로운 방법론 선택이 필요한 상황
Status
Accepted
Context
기존에 mildang-ui를 중심으로 사용하던 atomic design 한 구조에서 한계를 느껴 새로운 방법론 선택이 필요한 상황
- 크게 도메인별(customCurriculum, chat-bot)로 구분되어 있는 영역에서 참조에 대한 룰이 없다보니 순환참조로 인해 커플링이 되고 God object 들이 발생해서 코드 파악이나 리펙토링의 어려움
- molecules, patterns, recipes 등 여러 계층이 정리가 안되어 혼란
- 처음에는 mildang-ui storybook이 느려서 도메인 별로 패키지를 나누려 했으나 도메인별로 나누면 패키지 순환참조 문제가 발생하고 해결 불가능함
- 같은 기능에 대한 중복코드가 많아서 재사용성이 떨어짐
- 많은 개발이 이뤄지는 에디터 영역이 위 문제들로 개발 생산성 저하
Decision
Feature-Sliced Design 방법론을 사용한다.
layers: shared, entities, learning, features, pages, app slice: slice group이 필요하다면 사용 segments: ui, model, api, lib, config, extension
- 하위 레이어 단방향 참조와 slice 끼리는 참조를 못하는 규칙으로 순환 참조 문제를 해결하고 modularity, decouple-ability, testability 향상
- entities, learning, features, pages 레이어 분리로 도메인적인 컴포넌트나, 기능적인 컴포넌트나 로직에 대해 재사용성 향상
- slice/segment 마다 public API 방식을 활용하여 외부에 노출할 것들 명시적으로 정의하고 불필요한 노출을 통제함으로써 리펙토링을 용이하게
- FSD tool을 사용하여 설계적 구조를 지키지 않았을때 경고를 나오게 해서 maintainability 유지
learning layer
여러 학습 기능들이 에디터 중심으로 만들어져서 feature에 있는 액티비티 편집, 학습, 결과 기능들에서 소비가 되어야 하고 entity에 있는 공통인 부분(activity-editor, estimation 로직)들을 사용해야 해서 entity, feature 중간 레이어가 추가
extension segment
tiptap에 연동을 목적으로 하는 코드들이 위치하는 장소 node, mark 또는 기능을 담당하는 코드들 존재
파일 구조 예시
├── entities
│ ├── activity-editor
│ │ ├── extension
│ │ │ └── EstimationNode
│ │ │ └── currentFocus
│ │ │ ├── currentFocus.test.ts
│ │ │ ├── currentFocus.ts
│ │ │ └── index.ts
│ │ ├── index.ts # public api
│ │ └── ui
│ │ └── CMSBlockWrapper
│ │ ├── CMSBlockWrapper.stories.tsx
│ │ ├── CMSBlockWrapper.tsx
│ │ └── index.ts
│ ├── document-editor
│ │ ├── extension
│ │ │ ├── globalNodeId
│ │ │ ├── image
│ │ │ │ ├── image.test.ts
│ │ │ │ ├── image.ts
│ │ │ │ └── index.ts
│ │ │ └── slash
│ │ └── ui
│ │ └── BubbleMenu
│ └── user
│ ├── api
│ │ └── useUserLike
│ └── ui
│ └── UserProfileAvatar
├── features
│ └── activity-content # slice group
│ ├── edit
│ │ └── ui
│ │ └── ActivityContentEditor
│ ├── result
│ └── study
│ └── ui
│ └── ActivityContentStudy
├── learning
│ ├── math-graph
│ ├── multiple-choice
│ ├── short-answer
│ │ ├── extension
│ │ │ ├── shortAnswerAlternativeItemNode.ts
│ │ │ ├── shortAnswerAlternativeListNode.ts
│ │ │ ├── shortAnswerExtension.ts
│ │ │ ├── shortAnswerItemNode.ts
│ │ │ └── shortAnswerListNode.ts
│ │ └── ui
│ │ └── ShortAnswerItemEdit
│ └── word-memorization
├── pages
│ └── edit-meta-content-module
│ ├── model
│ │ ├── currentActiveNodeStore.test.ts
│ │ └── currentActiveNodeStore.ts
│ └── ui
│ ├── AddBlockActivityButton
│ ├── MetaContentModuleEditScreen
│ ├── MetaContentModuleEditScreenLeftSidebar
│ ├── MetaContentModuleEditScreenRightSidebar
│ └── MetaContentModuleEditScreenHeader
└── shared
└── ui
├── Button
│ ├── Button.stories.tsx
│ ├── Button.tsx
│ └── index.ts
└── ChipConsequences
장점
modularity, testability, decouple-ability, extensibility 설계적 특성들 개선
단점
권장 하지 않은 learning 레이어 추가로 인해 표준화된 구조 변형
모호하게 생각되는 분류가 있을 수 있지만(feature로 했지만 계층 참조 규칙으로 재사용을 위해 하위 레이어로 내려야 하는 경우) 장점으로 판단하는 다른 특성이 더 중요하다고 판단하고 비유를 하자면 레이어는 집에 방을 나누는 기준인데 부엌에서 요리를 하고 밥을 먹어야겠지만 방에서 무언가를 먹거나 부엌에서 책을 보는 것처럼 덜 중요한 문제라 판단