Clean Architecture란 무엇인가?
위의 클린 아키텍쳐 다이어그램은 여러 아키텍쳐가 가지고 있는 아래의 특징들을 전부 실행 가능한 하나의 아이디어로 통합하려는 시도이다.
클린 아키텍쳐의 특징
- 프레임 워크 독립성
- 프레임 워크의 존재 여부에 의존하지 않는다. (도구로써 프레임워크를 사용한다)
- 테스트 용이성
- 비즈니스 로직은 UI, Database, Web Server, 기타 외부 요소가 없어도 테스트할 수 있다.
- UI 독립성
- 시스템의 나머지 부분을 변경하지 않고도 UI를 변경할 수 있어야한다
- DB 독립성
- DB(MS SQL, 몽고 등)가 교체되어도 이상없이 동작해야한다.
- 비즈니스 로직은 데이터 베이스에 결합되지 않는다
- 모든 외부 에이전시에 대한 독립성
- 비즈니스 로직은 외부세계와의 인터페이스에 대해 전혀 알지 못한다
위의 다이어그램에서 바깥 쪽 원은 메커니즘을 안쪽 원은 정책을 뜻한다. 안쪽으로 갈 수록 고수준의 소프트웨어가 된다.
이러한 아키텍쳐가 동작하도록 하는 가장 중요한 규칙은 의존성 규칙이다. 의존성은 반드시 안쪽으로, 고수준의 정책을 향해야 한다.
내부의 원은 외부의 원에 속한 어떠한 것도 알지 못한다. 따라서 외부의 원에 선언된 어떠한 것도 언급해서는 안된다. 같은 이유로 외부의 원에 선언된 데이터 형식도 내부의 원에서 사용돼서는 안된다. 특히 데이터 형식이 외부의 프레임워크가 생성한 것이라면 더더욱 안된다.
Entities (Enterprise Business Roles)
- 전사적인 핵심 비즈니스 로직을 캡슐화 한다.
- 메서드를 가지는 객체이거나 데이터 구조와 함수의 집합일 수도 있다.
- 다양한 애플리케이션에서 엔티티를 재사용할 수만 있다면, 형태는 중요하지 않다.
- 단일 어플리케이션을 작성하고 있다면 엔티티는 해당 애플리케이션의 업무 객체가 된다.
- 이 경우는 엔티티는 가장 일반적이고 고수준인 규칙을 캡슐화 한다.
- 외부의 무언가가 변경되더라도 엔티티가 변경될 가능성은 지극히 낮아야한다.
Use cases (Application Business Roles)
- 애플리케이션에 특화된 업무 규칙을 포함한다.
- 모든 유스케이스를 캡슐화하고 구현한다.
- 엔티티로 들어오고 나가는 데이터 흐름을 조정하며, 엔티티는 핵심 업무 규칙을 사용해 유스케이스의 목적을 달성하도록 이끈다
- 운영 관점에서 애플리케이션이 변경된다면, 유스케이스가 영향을 받으며 이 계층의 코드 일부는 영향을 받을 것이다.
Interface Adapters
- 일련의 어댑터들로 구성
- 유스케이스와 엔티티에게 편리한 데이터 → 외부 에이전시에게 편리한 데이터
- 이 계층은 GUI의 MVC 아키텍쳐를 모두 포괄한다.
- Presenter, View, Contoller는 모두 해당 계층에 속한다.
- Model은 데이터 구조일 뿐이고 컨트롤러에서 유스케이스로 전달되고 다시 유스케이스에서 프레젠터와 뷰로 되돌아간다.
- 외부에서 들어온 데이터를 유스케이스나 엔티티에서 사용되는 내부적인 형식으로 변환하는 또다른 어댑터가 필요하다
Frameworks & Drivers
- 해당 계층은 데이터베이스나 프레임 워크같은 도구들로 구성된다.
- 따라서 해당 계층에서는 안쪽 계층과 통신하기 위한 접합 코드 외에는 특별히 더 작성해야될 코드가 많지않다.
계층은 꼭 4개여야만 하는가?
- 해당 계층은 그저 개념을 설명하기 위한 하나의 예시일 뿐, 항상 네 개의 계층만 사용해야한다는 규칙은 없다.
- 다만 어떤 경우에도 의존성의 규칙(의존성은 고수준으로 향해야하는)은 적용된다.
- 바깥쪽의 원은 저수준의 세부사항으로 구성되어야 하며, 안쪽으로 갈수록 점점 추상화 되고 높은 수준의 정책들을 캡슐화 하여야 한다.
- 따라서 가장 안쪽 원은 가장 범용적이며 높은 수준을 가져야한다.
경계 횡단하기
클린 아키텍쳐에서의 제어 흐름은 컨트롤러에서 시작되어 Use Case를 지나 Presenter에서 실행되면서 마무리 된다. 그와 반대로 의존성의 경우 Use Case를 향해 안쪽을 가르키게 된다.
이렇게 제어의 흐름과 의존성의 방향이 반대되어야 하는 경우 대체로 의존성 역전의 원칙(DIP)를 사용하여 해결한다.
경계를 가로지르는 데이터의 모습
앞서 설명한 클린아키텍쳐의 특징에서 나오듯이 내부 계층은 외부 계층에 대해 알 수 없기 때문에 내부 계층으로 횡단할 데이터는 의존성을 가져서는 안된다.
따라서 경계를 가로질러 데이터를 전달할 때는 항상 내부의 계층에서 사용하기 편리한 형태를 가져야 한다.
안드로이드에서의 클린 아키텍쳐
클린 아키텍쳐에서 말하는 특징들과 각 계층의 정의를 충실히 지켜서 작성한 계층 구조와 제어 흐름의 모습이다.
Presentation, Data 모듈은 프레임 워크와 관계를 갖기 때문에 인터페이스 계층에, Domain 모듈은 비즈니스 로직과 Use Case를 구현하기 때문에 Use Case 계층에 작성되었다.
핵심적인 비즈니스 로직을 담당하는 엔티티 계층을 작성해야 한다면 Entity 모듈을 만들어 비즈니스 로직을 작성하고 이를 Use Case에서 참조하여 사용하는 것이 가장 바람직한 방법일 것이다.
구글에서 제시한 어플리케이션 아키텍쳐
다음은 구글에서 제시한 아키텍쳐이다.
클린 아키텍쳐의 몇몇 특징들(안쪽으로 갈 수록 고수준의 소프트웨어가 된다, 안쪽으로 갈 수록 추상화 되어야 한다 등)을 제외 한다면 클린 아키텍쳐의 특징과 유사한 점이 많을 것이다.
그 이유는 이렇게 패턴화된 시스템 아키텍쳐들의 목표는 모두 관심사 분리이기 때문이다
각각의 레이어의 역할은 다음과 같다.
- UI 레이어
- UI 레이어는 애플리케이션 데이터 변경사항을 UI가 표시할 수 있는 형식으로 변환한 후에 표시하는 파이프라인
- 데이터 레이어
- 비즈니스 로직은 앱에 가치를 부여하는 요소로, 애플리케이션의 데이터 생성, 저장, 변경 방식을 결정하는 실제 비즈니스 규칙으로 구성
- 도메인 레이어(optional)
- 복잡한 비즈니스 로직이나 여러 ViewModel에서 재사용되는 간단한 비즈니스 로직의 캡슐화
조만간 시간이 난다면 해당 구조의 구체적인 예시를 소스와 함께 포스팅하도록 하겠다.
'Development > Android' 카테고리의 다른 글
Android 배포자동화(fastlane + github actions) - Part.4 (0) | 2022.04.20 |
---|---|
Android 배포자동화(fastlane + github actions) - Part.3 (0) | 2022.04.11 |
Android 배포자동화(fastlane + github actions) - Part.2 (0) | 2022.04.05 |
Android 배포자동화(fastlane + github actions) - Part.1 (0) | 2022.03.30 |
[번역] CameraX 기초 예제 - Part 3 (0) | 2022.02.11 |