FE에서 도메인 중심 설계를 위한 MV-VI 패턴 #755
psy082
started this conversation in
Suggest New Strategy
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
패턴 제목
FE에서 도메인 중심 설계를 위한 MV-VI 패턴
문서 위계
응집도 > 기능 응집하기 > X. FE에서 도메인 중심 설계를 위한 MV-VI 패턴
개요
React 생태계에서 훅은 강력하지만, 도메인 로직과 구현 세부사항(서버 상태 관리, 캐싱, 로딩/에러 처리)이 한 곳에 뒤섞이기 쉽습니다. 이로 인해 비즈니스 규칙이 특정 라이브러리에 강하게 결합되고, 페이지 컴포넌트가 구현 세부사항까지 알아야 하는 상황이 생깁니다.MV-VI 패턴은 도메인 인터페이스(M)와 뷰 구현체(VI)를 분리하여, Model과 View가 선언적으로 유지되면서 런타임 복잡성은 VI에 격리되도록 합니다.
내용
문제제기
FE에서도 도메인 로직 중심, 인터페이스 중심 설계가 가능해야 합니다. 그러나 React의 훅 패턴은 이를 어렵게 만듭니다.
📝 코드 예시
장바구니 기능을 구현한 훅입니다.
👃 코드 냄새 맡아보기
Myers의 응집도 관점에서 이 훅은 Logical 응집에 가깝습니다. "장바구니와 관련된 것들"이라는 느슨한 기준으로 묶여 있을 뿐, 변경 이유가 다른 코드들이 섞여 있습니다.
1. 도메인 로직과 구현 세부사항이 뒤섞여 있습니다
totalPrice계산은 순수한 비즈니스 규칙입니다. React Query가 SWR로 바뀌어도 이 규칙은 변하지 않아야 합니다. 그러나 지금은 같은 함수에 섞여 있어서 분리하기 어렵습니다.2. "장바구니"의 정의가 라이브러리에 묶여 있습니다
useCart가 반환하는 타입이 곧 장바구니의 정의입니다.isAdding은 React Query의isPending에서 온 것인데, 이게 도메인 인터페이스에 포함되어 있습니다. 라이브러리를 바꾸면 인터페이스도 바뀝니다.3. 페이지 컴포넌트가 구현 세부사항을 알아야 합니다
4. 성능 최적화가 외부에 영향을 줍니다
캐싱 전략을 바꾸거나, 여러 쿼리를 조인하거나, TanStack DB로 마이그레이션하려면 훅의 반환 타입이 바뀔 수 있고, 이는 사용하는 모든 곳에 영향을 줍니다.
✏️ 개선해보기
MV-VI 패턴으로 분리합니다.
VI가 Informational 응집(데이터와 그 데이터를 다루는 모든 것을 묶음)을 의도적으로 수용하는 대신, M과 V가 Functional 응집에 가까워질 수 있습니다.
1단계: Model — 도메인 인터페이스 정의
React를 모르는 순수 타입 정의입니다. "장바구니란 무엇인가"만 정의합니다.
2단계: View Implementation — 훅 구현체
도메인 인터페이스
Cart를 React 환경에서 구현합니다. 서버 상태 관리, 데이터 조인, 캐싱이 모두 여기에 있습니다.CartImpl은Cart를 확장합니다.isAdding,isRemoving같은 속성은 서버 상태 관리의 부산물이고, 도메인 관점에서는 필요 없지만 UI를 위해 VI에서 확장합니다.3단계: View Implementation — 컨트롤러 컴포넌트
Suspense와 ErrorBoundary를 강제하고, 훅을 직접 노출하지 않습니다. 이 컴포넌트가 MV-VI의 핵심입니다. 이 컴포넌트가 있음으로써 페이지 컴포넌트가 도메인 로직 중심으로 뷰를 표현할 수 있습니다.
컨트롤러 컴포넌트의 역할:
useCart를 직접 import할 수 없음4단계: View — 페이지 컴포넌트
페이지 컴포넌트는 도메인 인터페이스만 알고, 선언적으로 UI를 정의합니다.
페이지 컴포넌트가 모르는 것들:
페이지 컴포넌트가 아는 것:
Cart인터페이스 (items, totalPrice, add, remove...)VI의 자유도
VI 내부는 자유롭게 바꿀 수 있습니다. M의 인터페이스를 만족하는 한 V는 영향받지 않습니다.
이 변경들이 VI 안에서 일어나므로, 페이지 컴포넌트는 수정할 필요가 없습니다.
같은 VI, 다른 UI
headless 패턴으로 같은
Cart컨트롤러를 다양한 UI로 렌더링할 수 있습니다.폴더 구조와 Colocation
VI의 위치는 재사용 범위에 따라 결정합니다. 구조는 동일합니다.
핵심은 위치가 어디든 M-VI-V 구조는 동일하다는 것입니다.
전체 의존 방향
불안정한 코드(V)가 안정적인 코드(M)에 의존합니다. 역방향 의존이 없습니다.
🔍 개선 효과
정리
MV-VI 패턴은 FE에서 도메인 중심 설계를 가능하게 합니다.
VI가 Informational 응집을 의도적으로 수용함으로써, M과 V가 Functional 응집에 가까워지고 선언적으로 유지될 수 있습니다.
All reactions