SW 개발 일반/아키텍처

클린 아키텍처란 무엇인가?

growdai1y 2025. 1. 16. 12:32

클린 아키텍처(Clean Architecture)는 소프트웨어 설계 원칙을 통해 시스템의 유지보수성과 확장성을 극대화하려는 개발 방법론입니다. 로버트 C. 마틴(Uncle Bob)이 제안한 이 개념은 의존성 역전(DIP: Dependency Inversion Principle)을 중점으로, 비즈니스 로직과 UI, 데이터 계층 간의 결합도를 낮추는 데 초점을 맞춥니다.


Screaming Architecture (스스로 외치는 아키텍처)

Screaming Architecture는 소프트웨어의 아키텍처가 "이 시스템이 무엇을 하는지"를 명확히 드러내야 한다는 개념을 의미합니다. 즉, 디렉토리 구조와 코드 네이밍이 시스템의 주요 비즈니스 목적을 전달해야 한다는 것입니다. 이를 통해 새로운 개발자가 코드를 처음 접했을 때도 어떤 기능과 목적을 가진 소프트웨어인지 직관적으로 이해할 수 있습니다.

Screaming Architecture
Screaming Architecture

예를 들면 아래 디렉토리 구조는 "Feature1"과 "Feature2"라는 도메인 중심의 구성을 통해 프로젝트의 주요 기능이 무엇인지 명확히 드러내고 있습니다. 각 계층과 파일 이름 또한 도메인 중심적으로 설계되어 소프트웨어의 목적을 분명히 표현합니다. 스스로 무엇을 하는지 잘 보여주는 Screaming Architecture의 좋은 예라고 할 수 있습니다.

app/
└── src/
    └── main/
        ├── java/
        │   └── com.example.app/
        │       ├── di/                  # Dependency Injection (Dagger/Hilt modules)
        │       ├── presentation/        # Feature별 UI, MVP 패턴 View & Presenter
        │       │   ├── base/            # Base classes for MVP
        │       │   ├── feature1/        # Feature 1 관련 Presentation 코드
        │       │   │   ├── Feature1Activity.kt
        │       │   │   ├── Feature1Fragment.kt
        │       │   │   ├── Feature1Presenter.kt
        │       │   │   ├── Feature1View.kt
        │       │   ├── feature2/        # Feature 2 관련 Presentation 코드
        │       │       ├── Feature2Activity.kt
        │       │       ├── Feature2Fragment.kt
        │       │       ├── Feature2Presenter.kt
        │       │       ├── Feature2View.kt
        │       ├── domain/              # Use cases and business logic
        │       │   ├── feature1/        # Feature 1 도메인 코드
        │       │   │   ├── model/
        │       │   │   ├── repository/
        │       │   │   ├── usecase/
        │       │   │       ├── GetFeature1DataUseCase.kt
        │       │   ├── feature2/        # Feature 2 도메인 코드
        │       │       ├── model/
        │       │       ├── repository/
        │       │       ├── usecase/
        │       │           ├── GetFeature2DataUseCase.kt
        │       ├── data/                # Data layer
        │       │   ├── feature1/        # Feature 1 데이터 레이어
        │       │   │   ├── repository/
        │       │   │   │   ├── Feature1RepositoryImpl.kt
        │       │   │   ├── datasource/
        │       │   │       ├── local/
        │       │   │       │   ├── Feature1LocalDataSource.kt
        │       │   │       ├── remote/
        │       │   │           ├── Feature1RemoteDataSource.kt
        │       │   ├── feature2/        # Feature 2 데이터 레이어
        │       │       ├── repository/
        │       │       │   ├── Feature2RepositoryImpl.kt
        │       │       ├── datasource/
        │       │           ├── local/
        │       │           │   ├── Feature2LocalDataSource.kt
        │       │           ├── remote/
        │       │               ├── Feature2RemoteDataSource.kt
        │       ├── utils/               # Utility classes and extensions
        │       └── App.kt               # Application class
        ├── res/                         # Android resources (layouts, drawables, etc.)
        └── AndroidManifest.xml

 


디렉토리 구조 분석

제시된 디렉토리 구조는 클린 아키텍처의 기본 원칙을 따르고 있으며, 각 계층을 독립적으로 설계하여 변경의 영향을 최소화합니다.

주요 계층 설명

1. Presentation Layer (presentation/)

  • 역할: 사용자 인터페이스(UI)를 관리하며 사용자와 상호작용합니다. MVP(Model-View-Presenter) 패턴을 활용하여 View와 Presenter를 분리합니다.
  • 구성요소:
    • base/: 공통으로 사용할 수 있는 View와 Presenter의 베이스 클래스.
    • feature1/, feature2/: 기능별 UI 화면(Activity, Fragment) 및 Presenter 구현.
      • Presenter는 Domain Layer의 UseCase 호출합니다.

2. Domain Layer (domain/)

  • 역할: 비즈니스 로직의 중심으로, 앱의 규칙과 로직을 관리합니다.
  • 구성요소:
    • model/: 도메인에서 사용하는 데이터 모델.
    • repository/: 데이터 접근을 정의한 인터페이스.
    • usecase/: 특정 비즈니스 작업을 처리하는 유스케이스 클래스.

3. Data Layer (data/)

  • 역할: 데이터 소스(로컬 또는 원격 API)에서 데이터를 가져오고, Domain 계층으로 전달합니다.
  • 구성요소:
    • repository/: Domain 계층의 Repository 인터페이스를 구현.
    • datasource/:
      • local/: 로컬 데이터베이스(SQLite, Room 등).
      • remote/: 원격 API 호출을 처리.

4. 기타 구성

  • utils/: 앱 전반에서 사용할 수 있는 유틸리티 클래스 및 확장 함수.
  • di/: Dependency Injection 구성. (Android에서는 주로 Dagger 프레임워크 사용)
  • App.kt: 애플리케이션 초기화를 위한 클래스.
  • 위 디렉토리 구조에는 테스트를 위한 별도의 디렉토리는 포함되지 않았으나, 이 구조를 기반으로 단위 테스트, 통합 테스트, E2E 테스트를 체계적으로 구성할 수 있습니다. 각 테스트 목적에 맞는 환경을 명확하게 설계하고 유지보수하기에도 적합합니다.

클린 아키텍처의 장점

  1. 유지보수성: 각 계층이 독립적이므로 변경 사항이 다른 계층에 미치는 영향을 최소화합니다.
  2. 테스트 용이성: 비즈니스 로직이 UI와 분리되어 있어 유닛 테스트 작성이 쉽습니다.
  3. 확장성: 새로운 기능 추가 시 기존 코드에 대한 영향을 줄일 수 있습니다.
  4. 가독성: 명확한 계층 구분으로 코드 구조를 이해하기 쉽습니다.

클린 아키텍처의 단점

  1. 초기 설정 비용: 계층 구분 및 설정 작업으로 초기 개발 시간이 길어질 수 있습니다.
  2. 복잡성 증가: 단순한 프로젝트에서는 불필요하게 복잡해질 수 있습니다.
  3. 학습 곡선: 팀원들이 아키텍처와 관련 패턴을 숙지하는 데 시간이 필요합니다.

클린 아키텍처가 적합한 프로젝트

클린 아키텍처는 모든 프로젝트에 적합하지는 않습니다. 다음 조건에 해당하는 프로젝트에 적용하는 것이 좋습니다:

  1. 장기적인 유지보수가 필요한 경우: 팀원 교체나 기능 추가가 빈번하다면 구조화된 아키텍처가 유리합니다.
  2. 복잡한 비즈니스 로직을 다루는 경우: 도메인 계층을 중심으로 로직을 정리하면 변경 및 확장이 용이합니다.
  3. 테스트가 중요한 경우: 핵심 로직을 테스트 가능하도록 설계해야 할 때 적합합니다.
  4. 다수의 데이터 소스를 사용하는 경우: 여러 데이터 소스를 통합하기 위해 Data Layer의 역할이 중요합니다.

결론

클린 아키텍처는 소프트웨어 설계의 품질을 높이고, 장기적인 프로젝트 성공 가능성을 극대화합니다. 하지만 초기 설정 비용과 학습 곡선을 고려해야 하므로, 프로젝트의 규모와 요구사항을 명확히 분석한 후 도입 여부를 결정해야 합니다.

 

이 글을 통해 클린 아키텍처의 개념과 구조를 이해하고, 본인의 프로젝트에 적합한지 판단하는 데 도움이 되었기를 바랍니다. 앞으로도 클린한 코드와 아키텍처로 개발 생산성을 높여 보세요!

 

매일 성장하기

반응형

'SW 개발 일반 > 아키텍처' 카테고리의 다른 글

(2) FSD의 핵심 계층과 역할  (0) 2025.02.10
(1) FSD란 무엇인가?  (0) 2025.02.08