-
[Design Patten] 관심사의 분리카테고리 없음 2023. 12. 11. 11:58
개요
- 주요 개념
- 관심사 분리의 장점
- 주의사항 및 요점
주요 개념
직교성)
A와 B가 직교하는 경우 A를 변경해도 B는 변경되지 않아야하며 반대상황도 마찬가지다.
ex) 라디오의 볼륨 조절과 채널 조절은 서로에게 영향을 주면 안된다.이렇듯 좋은 React 애플리케이션 디자은은 다음과 같은 관심사가 직교한다.
- UI 요소 (presentaion component)
- 레이아웃 (layout)
- 데이터 페치 컴포넌트 (stateful)
- 데이터 렌더링 컴포넌트 (stateless)
- 서스펜스 / 에러바운더리 (statefull)
- 데이터 가져오기(fetch 라이브러리, REST or GraphQL)
- 글로벌 상태관리 (Redux, Recoil, ContextAPI)
- 영속성 로직 (localstorage, cookie...)
이러한 직교성을 통해서 변경사항은 격리되고 하나의 컴포넌트에 집중이 가능해 예측 가능하고 개발하기 쉬운 시스템을 만들 수 있다.
데이터를 가져오는 과정을 분리해보자)
import React, { useState } from 'react'; import axios from 'axios'; import EmployeesList from './EmployeesList'; function EmployeesPage() { const [isFetching, setFetching] = useState(false); const [employees, setEmployees] = useState([]); useEffect(function fetch() { (async function() { setFetching(true); const response = await axios.get("/employees"); setEmployees(response.data); setFetching(false); })(); }, []); if (isFetching) { return <div>Fetching employees....</div>; } return <EmployeesList employees={employees} />; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
suspense를 이용해서 data fetch과정을 분리할 것임.
1. 완성
import React, { Suspense } from "react"; import EmployeesList from "./EmployeesList"; function EmployeesPage({ resource }) { return ( <Suspense fallback={<h1>Fetching employees....</h1>}> <EmployeesFetch resource={resource} /> </Suspense> ); } // fetch 로직을 포함한 컴포넌트 function EmployeesFetch({ resource }) { const employees = resource.employees.read(); return <EmployeesList employees={employees} />; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
UI와 hook을 분리해보자)
import React, { useState, useEffect } from 'react'; const DISTANCE = 500; function ScrollToTop() { const [crossed, setCrossed] = useState(false); useEffect( function() { const handler = () => setCrossed(window.scrollY > DISTANCE); handler(); window.addEventListener("scroll", handler); return () => window.removeEventListener("scroll", handler); }, [] ); function onClick() { window.scrollTo({ top: 0, behavior: "smooth" }); } if (!crossed) { return null; } return <button onClick={onClick}>Jump to top</button>; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
UI로직과 스크롤 리스너 로직(useEffect 내부 로직)를 분리할 것임
1. hook을 통한 리스너 로직 분리
import { useState, useEffect } from 'react'; function useScrollDistance(distance) { const [crossed, setCrossed] = useState(false); useEffect(function() { const handler = () => setCrossed(window.scrollY > distance); handler(); window.addEventListener("scroll", handler); return () => window.removeEventListener("scroll", handler); }, [distance]); return crossed; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
2. UI로직
function onClick() { window.scrollTo({ top: 0, behavior: 'smooth' }); } function JumpToTop() { return <button onClick={onClick}>Jump to top</button>; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
3. 격리를 위한 추가 컴포넌트
function IfScrollCrossed({ children, distance }) { const isBottom = useScrollDistance(distance); return isBottom ? children : null; } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
4. 완성
import React from 'react'; // ... const DISTANCE_NEWSLETTER = 300; function OtherComponent() { // ... return ( <IfScrollCrossed distance={DISTANCE_NEWSLETTER}> <SubscribeToNewsletterForm /> </IfScrollCrossed> ); } 출처: https://itchallenger.tistory.com/541#google_vignette [Development & Investing:티스토리]
변경될 수 있는 사항을 별도의 컴포넌트로 분리를 하는 것이 직교성의 핵심이다!
장점
- 모든 변경사항이 컴포넌트 내에 격리가 되어 쉽게 변경사항에 대해 쉽게 조절할 수 있다.
- 컴포넌트가 한 개의 역할만을 수행함에 따라 쉽게 이해할 수 있다.
- 단일 책임구현에만 집중을 하므로 컴포넌트가 올바르게 수행하는지 테스트 할 수 있다.
주의사항
직교 설계는 You aren't gonna need it 원칙에 따라 균형을 이루므로 실제로 필요할 때 구현하고 미리 구현하지 마세요!
- 극단적인 설계를 피하고 필요에 따라 생성하는 것이 좋다.
- 변화를 예측하고 필요한 부분을 파악하는 능력을 길러보자!
가장 좋은 디자인의 핵심 원칙은 가장 변경 될 가능성이 높은 논리를 분리하는 것임 그렇기에 로직이 직교하도록 만드는 것
이러한 직교를 통해서 변경사항이나 새로운 기능 요구에 유연하게 적응할 수 있다.참고자료 : 블로그