클린 코드로 소프트웨어 공학의 대가 로버트 C.마틴이 제시한 소프트웨어 디자인 철학이다. 소프트웨어의 관심사를 계층별로 분리하여 코드 종속성이 외부로부터 내부로 의존하도록 하는 것이 주요 원칙이다. 따라서 내부 계층의 코드는 외부 계층의 기능을 알 수 없고,내부 계층 코드에서는 외부 계층에 존재하는 변수 및 함수, 클래스 등이 등장해선 안 된다. 즉, 내부 계층으로 갈수록 추상화된 계층이며 이는 SOLID 원칙의 DIP 를 따른 것이라고 볼수 있다.
설명에 따르면 위 그림에서 가장 내부에 있는 Entities
라는 영역이 가장 추상적인 영역이다. 이 영역은 소프트웨어의 비즈니스 로직을 포함하게 되고, 사용 중인 프레임워크 (안드로이드 등) 에 의존해선 안 된다. 반면 외부 계층은 네트워크 및 DB 의 접근처럼 프레임워크, 플랫폼에 특정한 구체적인 구현이 포함된다.
가장 큰 장점은 코드의 재사용성이 용이해진다는 점이다. 관심사에 따라 계층을 분리하고 계층간 의존성을 외부에서 내부로, 즉 단방향으로 만들었기 때문이다. 또한 유닛 테스트도 더욱 간편해질 것이다.
따라서, 궁극적으로 아래와 같은 사항들을 달성하기 위해 클린 아키텍처를 사용한다고 할 수 있다.
내부 계층에서 외부 계층의 존재를 알면 안 된다는 규칙만 지킨다면 꼭 위 사진처럼 계층을 나눌 필요가 없고 계층을 몇 개로 나누어도, 어떻게 나눠도 상관이 없다. 의존성 규칙만 잘 지키면되고, 항상 가장 바깥 계층에서 안쪽으로 참조하며, 안쪽 계층으로 들어갈 수록 추상화 및 캡슐화 수준이 높아지게 하면 된다.
가장 보편화된 클린 아키텍처 구조에선 크게 Entities
, Use Cases
, Interface Adapters
, Frameworks and Drivers
이렇게 4개 계층으로 나누게 된다. 따라서 이번 포스팅에선 각각 계층에 대해 살펴보도록 하자.
Domain Logic 이라고도 한다. 소프트웨어의 비즈니스 규칙을 캡슐화한다. 즉, 비즈니스 로직을 위한 데이터의 구조나 메소드 등을 포함하는 객체이다. 모든 어플리케이션은 하나 이상의 비즈니스 로직을 갖고 있다. 번역기 앱이라면 번역, 메모장 앱이라면 메모가 비즈니스 로직이 된다.
엔티티 계층은 어플리케이션의 비즈니스 로직을 담고, 가장 일반적이고 상위 수준의 규칙들을 캡슐화하는 것이다. 외부에서 무언가 변경되더라도 거의 영향을 받지 않아야 한다. 예를 들어 UI 가 변경되거나 DB 가 변경되어도 엔티티 계층은 영향받지 않아야 한다.
네트워킹 혹은 DB 동작과 관련된 데이터 클래스를 작성할텐데, 그러한 것들이 이 계층에 속한다고 보면 된다. 단 안드로이드 프레임워크와 관련된 코드를 포함해서는 안 된다. 순수한 코틀린 및 자바 코드만을 담고 있어야 한다.
만약 프레임워크 관련 코드가 담겨있을 경우 유닛 테스트가 불편해지기 때문이다.
Business Rules 라고도 한다. 어플리케이션과 관련된 비즈니스 규칙을 포함하고, 시스템의 모든 Use Case 구현체들을 캡슐화하는 계층이다. 이러한 유즈 케이스들은 엔티티로부터의 데이터 흐름들을 관리한다. 관심사별로 계층이 잘 분리된 형태이기 때문에 해당 계층은 엔티티에 영향을 미치지 않고, 마찬가지로 UI 나 DB, 프레임워크 등 외부 계층에서도 영향받지 않는다.
안드로이드로 따지면 Model
, Repository
, Executor
등과 관련된 내용이 해당 계층에 속한다.
해당 계층은 Entity 나 Use Case 로부터 얻은 데이터를 가공하는 계층이다. 즉, 얻은 데이터들을 DB 및 HTTP 요청, 혹은 UI 업데이트에 적용할 수 있는 형태로 변환한다. 순수한 비즈니스 로직만을 담당하게 된다. 해당 게층의 목적은 비즈니스 로직과 프레임워크 코드를 스무스하게 연결하는 것이다.
안드로이드로 따지면 ViewModel(MVVM)
, Presenter(MVP)
, View(MVVM, MVP)
, Controller(MVC)
등이 포함된다.
가장 외부 계층이다. 일반적으로 안드로이드에서는 UI 와 관련된 액티비티 (혹은 프래그먼트), Intent 전달, Room 과 같은 DB, Retrofit 과 같은 네트워킹 관련 프레임워크 코드들이 속한다. 따라서 이쪽 부분은 앱 개발자가 직접 건드릴 일이 없긴 하다.
이렇듯 관심사가 완전히 딱딱 분리된 형태를 사용하게 되면, 많은 코드가 방해받지 않고 특정 문제 및 상황에 집중할 수 있다. SOLID 원칙을 잘 따른 패턴이다. 다만 클린 아키텍처에는 절대 정답이 없다. 관심사만 잘 분리된다면 어떤 형태를 가지든 원칙은 변하지 않는 것이다.
기회가 된다면 다음 포스팅에선, 안드로이드에 보다 더 특화된 클린 아키텍처를 소개하고, 이에 따라 구현한 앱 프로젝트에 대해 소개해보려고 한다.
도서 '아키텍처를 알아야 앱 개발이 보인다' - 옥수환 저