Clean Architecture로 리액트 폴더구조 설계하기

이수연·2023년 10월 29일
3

회사에서 오픈소스 프로젝트를 기반으로 자사 솔루션을 개발하면서, 많은 프로젝트가 클린 아키텍처로 설계된 것을 발견했다. 그래서 애자일을 창시한 로버트 C. 마틴의 '클린 아키텍처'를 읽고 깊이 이해하려 노력했다. 이를 바탕으로 클린 아키텍처의 폴더 구조를 혼자 설계하게 되었고, 덕분에 업무 시 코드 구조를 빠르게 파악할 수 있게 되었다. 이 경험을 바탕으로 클린 아키텍처에 대해 공유하고자 한다.

아키텍처의 중요성

로버트 C. 마틴의 클린아키텍처에서 서술하기를, 기능은 구조에 의지한다는것이다. 이 점을 이해하기 위해서는 코딩이라는 행위에 담겨져 있는 내재적 관점을 살펴 봐야 된다. 우리가 회사에 들어가서 하는 행위는 코딩 이다. 코딩의 목적성을 생각해 보면 다음과 같다.

코딩의 목적

컴퓨터에게 원하는 일(기능)을

  • 더 정확하게(버그 수정)
  • 더 빠르게(성능 개선)
  • 더 많이(기능 추가)

시키기 위한것 이다.

즉, 우리는 코드를 읽고, 이해 하고, 코드 수정/ 추가 하는 일을 많이 하게 되는것이다. 따라서 위와 같은 행위들을 할때, 우리는 제일 먼저 프로젝트의 구조를 먼저 파악 하는것이 우선적이게 되며, 이는 아키텍처와도 연관성을 가지게 된다. 잘 정돈된 방에서 물건을 찾을때와, 어지럽혀진 방에서 물건을 찾을때 그 속도의 차이가 많이 나는것과 같은것 이다.

우리가 회사에 입사하는 행위는 회사에 이익을 창출하기 위해서 이다. 회사의 입장에서는 최소한의 인력으로 최대의 이익을 창출해야되며 이는 소프트웨어 아키텍처의 목표인 '필요한 시스템을 만들고 유지보수하는 데 투입되는 인력을 최소화하는 것'과 상응하게 된다.

클린 아키텍처란?

로버트 C. 마틴이 제안한 방법으로 관심사를 확실히 분리하여 효율적으로 재사용성이 높은 컴포넌트를 구현 할수있게끔 만들수 있는 아키텍처 이다. 즉 최소한의 노력으로 최대의 효율을 얻게 해주는 것이다.

클린 아키텍처의 기본 이론

  • 체계적으로 계층이 분리되어야한다.
  • 각 계층은 서로 맡은 역할을 충실히 수행한다.
  • 계층간의 의존성 관계가 잘 이루어져야한다.

핵심 개념

  • 안쪽의 원(비즈니스 로직) 바깥의 원(UI나 data source)에 대해 전혀 알지 못한다.
  • 안쪽 영역으로 갈수록 추상화와 정책의 수준이 높아지며, 반대로 갈수록 구체적인 세부사항으로 구성된다.

클린아키텍처 구조의 이해

나는 클린아키텍처의 구조를 벤다이어그램과 비슷하다고 생각하였고, 벤다이어그램 형식으로 이해하였다. 아래의 그림과 같이 a집합은 모든 집합의 구성요소에 대해 알고 있다. b집합은 c,d집합의 구성요소에 대하여 알고있지만, a집합의 전체 구성요소를 알수 없다. 이와 같은 원리로 의존성에 대입하게 되면 클린아키텍처는 가장 안쪽으로 들어갈수록 의존성이 줄어 들게 되며 가장 안쪽에 있는 엔티티 영역에는 의존성이 없는 구성요소만 남게 되는것 이다.

클린 아키텍처 구조

클린아키텍처의 구조는 아래 사진과 같다. 구조는 위에서 말한 벤다이어그램 구조와 비슷하지만 다른점이 있다. 가장 바깥쪽에 있는 영역과 안쪽의 영역(core영역)을 이어주는 adapter영역(controller)영역이 추가되는것이다. 각각의 역할들은 아래에 정리해 보았다.

  • 엔티티 영역
  1. 가장 변하지 않고, 외부로부터 영향받지 않는 영역 이다.
  2. 핵심 업무(비즈니스 규칙) 규칙을 캡슐화한다.
  3. 특정 애플리케이션에 대한 운영 변경은 엔티티 계층에 영향을 주지 않아야 한다.
  • 유스케이스 영역
  1. 애플리케이션에 해당하는 비즈니스 규칙이 포함되어 있다.
  2. 시스템의 모든 사용 사례를 캡슐화하고 구현한다.
  3. 사용 사례는 엔터티와의 데이터 흐름을 조율한다.
  4. 데이터베이스, UI, 프레임 워크 등 외부 요소의 변경에 의해 영향을 받지 않는다.
  • 컨트롤러 영역
  1. 일련의 어댑터들로 구성된다.
  2. 어댑터는 데이터를 (유스 케이스와 엔티티에게 가장 편리한 형식)
    (데이터베이스나 웹 같은 외부 에이전시에게 가장 편리한 형식)으로 변환한다.
  • 웹 영역
  1. 시스템의 핵심 업무와는 관련 없는 세부 사항이다. 언제든 갈아 끼울 수 있다.
  2. 프레임워크나, 데이터베이스, 웹서버 등이 여기에 해당된다.
  3. 모든 세부사항들이 여기에 포함된다.

클린 아키텍처로 리액트 프로젝트 구성 하기

나는 위에서 설명한 이론을 토대로 아래와 같이 폴더구조를 구성해 보았다. 클린 아키텍처는 정형화된 패턴이 없기 때문에 개발자에 따라 구조가 달라질수 있다.

  • core 영역

    • entities, useCasese 폴더가 위치한 영역.

    • entities: 의존성에 영향 받지 않는 영역으로 typescript의 type들을 정의한 폴더가 포함되어 있다.

    • useCasese: 어플리케이션의 비즈니스 로직을 수행하는 영역으로 api 통신하는데 있어 중간다리 하는 역할을 하는 폴더로 구분 지었다. 가장 바깥쪽 영역에 있는 db 영역에 종속되면 안된다. 예) 사용자 로그인, 로그아웃, 비밀번호 재설정 등과 같은 인증 관련 로직을 처리, 사용자 정보의 CRUD (생성, 읽기, 업데이트, 삭제) 작업을 처리

  • controller 영역

    • core 영역과 가장 바깥쪽 영역을 연결해 주는 영역

    • pages 폴더, custom hook 폴더를 이영역에 포함 시켰다.

  • 가장 바깥쪽 영역 (웹, db, ui, 외부 인터페이스 등등)

    • 세부 사항 영역으로 가장 변동이 심한 영역

    • infrastructure(파이어 베이스(db)) , interfaces폴더 (useCasese 폴더에 종속 하면서 변동이 있는 영역으로 설계 하였다.) tests 폴더(컴포넌트 및 공통 함수 테스트), components폴더(공통 컴포넌트)

├─ src
│  ├─ App.css
│  ├─ App.tsx
│  ├─ assets
│  │  └─ react.svg
│  ├─ components
│  │  └─ Button
│  │     └─ index.tsx
│  ├─ core
│  │  ├─ entities
│  │  │  └─ User.entites.ts
│  │  └─ useCases
│  │     ├─ authentication.ts
│  │     └─ userManagement.ts
│  ├─ hooks
│  ├─ index.css
│  ├─ infrastructure
│  │  ├─ firebase
│  │  │  └─ index.ts
│  │  ├─ services
│  │  │  └─ index.tsx
│  │  └─ utilities
│  │     └─ index.tsx
│  ├─ interfaces
│  │  ├─ api
│  │  │  └─ index.tsx
│  │  └─ store
│  │     └─ index.tsx
│  ├─ main.tsx
│  ├─ pages
│  │  └─ index.tsx
│  ├─ utils
│  └─ vite-env.d.ts
├─ tests

0개의 댓글

관련 채용 정보