기능 분할 설계
기능 분할 설계
1. 레이어
- 최상위 디렉토리, 애플리케이션 분해의 첫 번째 단계
- 레이어의 수는 최대 7개로 제한
- 일부는 선택사항이자만 표준화 됨
1) 특징
각 레이어는 고유한 책임 영역이 있고, 비지니스 지향적이다.
*비지니스 지향적 : 소프트웨어가 비즈니스의 목적을 이해하고 그 목적을 달성하기 위해 필요한 로직과 데이터를 처리하는 데 중점을 둔다.
(1) app : 애플리케이션 로직이 초기화되는 곳
- 애플리케이션의 진입점 역할
- provider, router, 전역 스타일, 전역 타입 선언 등이 여기에서 정의
(2) processes(선택적 레이어): 여러 단계로 이루어진 등록과 같이 여러 페이지에 걸쳐 있는 프로세스를 처리
- 일종의 과거 방식
- 이 레이어는 더 이상 사용되지 않는 것으로 간주되지만 여전히 가끔씩 볼 수 있다.
- 최근 웹에서 주로 상태 관리 라이브러리나 contextAPI등을 사용하여 이러한 프로세스를 처리해서 필요가 없어짐
- 예를 들어, 사용자가 로그인을 시도하고 여러 페이지를 거쳐 로그인 상태를 유지하는 등의 프로세스를 다룸
- 하단 예시 코드
// processes 레이어: 여러 페이지에 걸쳐 있는 프로세스 처리
// 예시 프로세스 처리 함수
const handleLogin = (username, password) => {
// 로그인 처리 로직
if (username === 'user' && password === 'password') {
// 로그인 성공 시
console.log('로그인 성공');
} else {
// 로그인 실패 시
console.log('로그인 실패');
}
};
export { handleLogin };
(3) pages:애플리케이션의 페이지
(4) widgets : 페이지에 사용되는 독립적인 UI 컴포넌트
- 하단 예시 코드
// widgets 레이어: 독립적인 UI 컴포넌트
// 페이지에서 사용될 독립적인 UI 컴포넌트를 정의합니다.
// 예시 UI 컴포넌트
const Button = ({ onClick, text }) => {
return <button onClick={onClick}>{text}</button>;
};
export default Button;
(5) features(선택적 레이어) : 비즈니스 가치를 전달하는 사용자 시나리오와 기능
- 각각의 기능은 자체적으로 구현되고, 필요에 따라 다른 레이어의 기능을 활용 가능
- 비즈니스 로직을 담당하고, 데이터 처리나 외부 서비스와의 상호작용 처리
- 예를 들어, 좋아요, 리뷰 작성, 제품 평가
(6) entities(선택적 레이어) :비즈니스 엔티티
- 앱에서 다루는 중요한 개념이나 데이터 모델이 포함, 앱 전체에서 공유될 수 있음
- 예를 들어, 사용자, 리뷰, 댓글 등
(7) shared:특정 비즈니스 로직에 종속되지 않은 재사용 가능한 컴포넌트와 유틸리티
- 예를 들어, UI키트, axios 설정, 애플리케이션 설정, 비즈니스 로직에 묶이지 않은 헬퍼
- 하단 예시 코드
// shared 레이어: 재사용 가능한 컴포넌트와 유틸리티
// 비즈니스 로직에 종속되지 않은 재사용 가능한 컴포넌트와 유틸리티를 포함합니다.
// UI 키트
import { Button, Input } from 'ui-library';
// axios 설정
import axios from 'axios';
axios.defaults.baseURL = 'https://api.example.com';
// 애플리케이션 설정
const appName = 'MyApp';
// 헬퍼 함수
const capitalize = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
export { Button, Input, appName, capitalize };
이러한 레이어들은 특정한 역할을 수행하며,
그 역할에 따라 코드를 구성하고 관리합니다.
코드를 논리적으로 분할하여 각 부분을 독립적으로 유지할 수 있다.
이는 소프트웨어의 확장성과 유연성을 증가시키며, 새로운 기능을 추가하거나
기존 기능을 수정할 때 코드의 영향 범위를 최소화하여 유지보수를 쉽게 만든다.
2) 계층구조
기능 분할 설계의 주요 특징 중 하나는 계층 구조 이다.
위 레이어는 하위 레이어의 기능을 사용할 수 없다.
예를 들어, Features 레이어는 Entities 레이어의 기능을 사용할 수 없으며,
Widgets 레이어나 Processes 레이어의 컴포넌트를 직접적으로 사용할 수 없다.
이러한 구조는 각 레이어가 독립적으로 유지되도록 하여 코드의 의존성을 최소화하고,
유연하고 확장 가능한 아키텍처를 유지하는데 도움을 준다.
2. 슬라이스
각 레이어에는 애플리케이션 분해의 두 번째 수준인 슬라이스라는 하위 디렉토리가 있다.
1) 특징
(1) 슬라이스는 특정 비즈니스 엔티티에 대한 것으로, 비지니스 영역을 구성하는 핵심적인 부분이다.
(2)해당 영역에 관련된 코드를 그룹화하는 것이 목표
(3) 슬라이스 이름은 프로젝트의 비즈니스 영역에 따라 직접 결정되므로 표준화되어 있지 않다.
- 사진 갤러리에는 사진, 앨범, 갤러리와 같은 슬라이스
- 소셜 네트워크에는 게시물, 사용자, 뉴스피드와 같은 슬라이스
2) 주의
(1) 각 슬라이스는 독립적으로 유지되어야하며, 다른 슬라이스와의 의존성 최소화
=> 한 슬라이스의 코드는 다른 슬라이스의 코드와 직접적으로 연결되어서는 안된다.
(2) 예시
- 잘못된 예시
// 주문 슬라이스의 코드
const checkProductStock = (productId) => {
// 재고 확인을 위해 상품 슬라이스의 함수를 직접 호출
const stockQuantity = getProductStock(productId); // 잘못된 접근
return stockQuantity;
};
- 올바른 예시
이 경우, "주문" 슬라이스에서는 "상품" 슬라이스의 기능을 직접 호출하는 대신, 인터페이스를 통해 간접적으로 상호작용
이렇게 하면 각 슬라이스가 서로에게 직접 의존하지 않고, 서로간의 결합도를 최소화하여 유연하고 독립적으로 유지할 수 있다
// 주문 슬라이스의 코드
const checkProductStock = (productId) => {
// 상품 슬라이스의 기능을 호출하는 대신, 인터페이스를 통해 간접적으로 상호작용
const stockQuantity = productService.getProductStock(productId);
return stockQuantity;
};
3. 세그먼트
각 슬라이스는 다음과 같은 세그먼트로 구성된다:
- api: 서버 요청 처리 담당
- UI: 사용자 인터페이스 컴포넌트 구현
- model: 비즈니스 로직 처리 및 상태 관리
- lib: 보조 기능 제공
- config: 구성값 설정
- consts: 상수 값 정의
4. 공개API
각 슬라이드와 세그먼트에는 공개API가 존재
공개API : index.js, index.ts
=> 이 파일을 통해 슬라이스 또는 세그먼트에서 필요한 기능만 외부로 추출, 불필요한 기능은 격리
1) 공개API 규칙
// 공개 API 인덱스 파일
// 슬라이스의 공개 API 정의
export * from './features/userSlice'; // 사용자 슬라이스의 기능과 컴포넌트
export * from './features/productSlice'; // 제품 슬라이스의 기능과 컴포넌트
// 내부적으로만 사용되는 슬라이스
import internalSlice from './internalSlice'; // 내부 슬라이스
export { internalSlice }; // 외부에 공개하지 않음
(1) 애플리케이션 슬라이스와 세그먼트 사용: 공개 API에서 정의된 슬라이스의 기능과 컴포넌트만 사용
다시 말해, 공개 API에 명시된 슬라이스나 세그먼트에 있는 기능과 컴포넌트만 외부에서 사용 가능
다른 슬라이스나 세그먼트의 내부 요소에는 직접적으로 접근할 수 없으며, 격리된 상태로 유지
(2) 외부 접근 제한: 공개 API에 정의되지 않은 슬라이스나 세그먼트의 내부 부분은 외부에서 접근 불가능
이는 해당 부분이 다른 슬라이스나 세그먼트와 독립적으로 작동하고 외부에 공개되지 않아야 함을 의미
(3) 단순한 import 및 export: 공개 API는 import 및 export를 통해 단순하게 작동
이는 코드의 모든 곳에서 import를 변경할 필요 없이 애플리케이션을 변경할 수 있다는 것을 의미
즉, 공개 API를 통해 외부에서 필요한 기능이나 컴포넌트를 가져오고 사용할 수 있으며,
내부 구현의 변경이 있더라도 외부 코드에 영향을 미치지 않는다.
예제. Github Client
예제. Nike Sneaker and Footwear Store
예제. Sudoku