본문 바로가기

안드로이드/클린 아키텍처

[안드로이드 클린 아키텍처 시리즈] Domain Layer 설명 및 이론정리 #3


선택적 계층인 Domain Layer는 어떤 역할을 수행하고 있을까?

UI Layer와 Data Layer 사이에서 독립적으로 위치하여, 복잡한 비즈니스 로직이나 여러 ViewModel에서 재사용되는 간단한 비즈니스 로직의 캡슐화를 담당합니다. 중간 계층인 Domain Layer는 Data Layer를 의존할 것 같지만 Domain Layer는 어떤 계층에도 의존을 하지 않습니다. Repository Interface를 Domain Layer에서 정의하기 때문에 Data Layer에 의존을 하지 않아도 됩니다. (의존성 역전 법칙)

도메인 레이어의 역할

Domain Layer의 주요 구성 요소

Domain Layer는 다음과 같은 주요 구성 요소로 이루어집니다.

  • 엔터티 (Entity)
    엔터티는 비즈니스 로직의 핵심 데이터를 나타냅니다. 예를 들어, 사용자, 상품, 주문 등이 엔터티에 해당할 수 있습니다. 
  • 유스케이스 (UseCase)
    유스케이스는 애플리케이션에서 사용자가 수행할 수 있는 작업을 정의합니다. 각 유스케이스는 특정 비즈니스 로직을 캡슐화하고, 사용자의 요청을 처리한 후 결과를 UI Layer에 전달합니다.
  • 레포지토리 인터페이스 (Repository Interface)
    Domain Layer는 Date Layer로부터 데이터를 요청하기 위해 레포지토리 인터페이스를 사용합니다. 이 인터페이스를 통해, Domain Layer는 Data Layer의 구체적인 구현에 의존하지 않고 데이터를 요청할 수 있습니다. 실제 구현은 데이터 레이어에서 담당합니다. (의존성 역전 법칙)

1. 엔터티 (Entity)

엔터티는 비즈니스 로직의 핵심 데이터를 표현하는 객체로, 애플리케이션의 도메인 모델을 구성하는 기본 단위입니다. 엔터티는 비즈니스 도메인 내의 실제 세계 객체나 개념을 반영하며, 각 엔터티는 고유한 식별자와 함께 여러 속성을 가질 수 있습니다.

  • 역할
    엔터티는 비즈니스 로직의 주체로, 비즈니스 규칙을 적용하고, 다른 엔터티와의 관계를 관리합니다.
  • 예시
    사용자 엔터티는 이름, 이메일, 프로필 사진과 같은 속성을 가집니다. 상품 엔터티는 상품명, 가격, 설명 등의 속성을 포함합니다.

2. 유스케이스 (UseCase)

유스케이스는 사용자가 시스템을 통해 수행할 수 있는 작업을 정의한 것으로, 특정 비즈니스 로직을 캡슐화합니다. 각 유스케이스는 한 가지 기능적 요구사항을 만족시키는 작업을 수행하고, 결과를 반환합니다.

  • 역할
    유스케이스는 애플리케이션에서 사용자의 입력을 받아 처리하고, 적절한 출력을 생성합니다. 이 과정에서 필요한 데이터를 리포지토리로부터 요청하고, 비즈니스 규칙을 적용합니다.
  • 예시
    "로그인하기", "상품 주문하기", "프로필 정보 업데이트하기" 등이 유스케이스가 될 수 있습니다.

구글은 공식적으로 UseCase 이름 지정 규칙을 아래와 같이소개하고 있습니다.

  • 현재 시제의 동사 + 명사/대상(선택사항) + UseCase
  • 예시
    LogOutUserUseCase, GetLatestNewsWithAuthorsUseCase, MakeLoginRequestUseCase

3. 레포지토리 인터페이스 (Repository Interface)

레포지토리 인터페이스는 Domain Layer가 Data Layer로부터 필요한 데이터를 요청하는 방법을 정의합니다. 이 인터페이스를 통해, Domain Layer는 Data Layer의 구체적인 구현 방법을 몰라도 데이터를 요청하고 사용할 수 있습니다. 이는 SOLID 원칙 중 의존성 역전 원칙(Dependency Inversion Principle)의 적용 예입니다. Interface를 통해 추상화하지 않았다면 Domain Layer의 UseCase가 Data Layer의 Repository를 사용할 수 밖에 없습니다. 이렇게 되면 Domain Layer는 Data Layer에 의존성이 생겨나게 됩니다. 하지만 Repository를 Interface로 갖고 있음으로써 의존이 생겨나지 않게 됩니다. 그래서 Domain Layer는 어떤 계층에도 의존하지 않을 수 있게 되는 겁니다.

4. Domain Layer 정

Domain Layer는 어플리케이션의 구조에서 UI Layer와 Data Layer 사이에 위치하며, 이 두 계층을 연결하는 동시에 각각으로부터 독립적으로 기능합니다. Domain Layer의 주요 구성 요소는 엔터티(Entity), 유스케이스(UseCase), 그리고 레포지토리 인터페이스(Repository Interface)입니다. 이 계층의 설계는 의존성 역전 원칙(Dependency Inversion Principle)을 적용하여, 높은 수준의 모듈이 낮은 수준의 모듈에 의존하지 않도록 하여 양쪽 모두가 추상화에 의존하게 합니다.

5. 클린 아키텍처 이론 정리

클린 아키텍처는 애플리케이션의 유지보수성, 확장성, 그리고 테스트 용이성을 향상하기 위해 설계된 아키텍처입니다. 안드로이드 애플리케이션 개발에서 클린 아키텍처를 적용함으로써, 각 계층의 책임을 명확히 분리하고, 비즈니스 로직과 UI 로직을 분리하여 애플리케이션의 전체적인 품질을 향상시킬 수 있다고 생각합니다. 앞서 설명한 UI Layer, Domain Layer, Data Layer를 적용하면 아래 그림처럼 데이터 스트림이 형성됩니다.

클린 아키텍처의 전체 데이터 스트림

  • UI Layer
    사용자 인터페이스와 상호작용을 관리하며 ViewModel을 통해 사용자의 액션을 처리하고 데이터를 표시합니다.
  • Domain Layer
    비즈니스 로직이 적용되는 곳으로, UseCase를 통해 특정 작업을 정의하고 실행합니다. 또한, Repository Interface를 통해 필요한 데이터를 요청합니다.
  • Data Layer
    로컬 데이터베이스
    원격 API와 같은 다양한 데이터 소스와의 상호작용을 담당합니다. 데이터는 이곳에서 처리되고, 필요한 정보를 Domain Layer로 전달합니다.

클린 아키텍처는 구현해야 할 클래스가 많기도 하고 복잡하게 느껴지기도 합니다. 한 가지 기능을 추가하기 위해 많은 파일을 생성해야 하고, 협업을 진행한다면 모두가 클린 아키텍처에 대해서 정확하게 이해하고 있어야 하는 등의 노력이 필요하게 됩니다. 그럼에도 이런 아키텍처를 설계하고 사용하는 이유를 구글에서는 아래처럼 설명하고 있습니다.

  • 앱의 전반적인 유지관리성, 품질, 견고성이 개선됩니다.
  • 앱을 확장할 수 있습니다. 코드 충돌이 최소화되어 더 많은 인력과 팀이 동일한 코드베이스에 기여할 수 있습니다.
  • 온보딩에 도움이 됩니다. 아키텍처는 프로젝트에 일관성을 부여하므로 새로운 팀원이 빠르게 업무를 시작하고 보다 짧은 시간에 효율을 높일 수 있습니다.
  • 테스트하기가 더 쉽습니다. 좋은 아키텍처는 테스트하기가 더 쉬운 간단한 유형을 사용하도록 지원합니다.
  • 잘 정의된 프로세스를 사용하여 버그를 체계적으로 조사할 수 있습니다.

다음 포스팅에서는 안드로이드 스튜디오에서 클린 아키텍처를 구현하는 방법에 대해 다루어 보겠습니다.