본문 바로가기
Concepts/SW Architecture

아키텍처 - 클린 아키텍처

by ocwokocw 2021. 2. 10.

- 이 글은 로버트 C.마틴의 Clean Architecture를 기반으로 작성되었습니다. (가능하면 책을 읽어보는것을 추천한다.)

- 개요

지난 수십년간 많은 시스템 아키텍처가 있었다. 이런 아키텍처들은 공통된 목표가 있는데 바로 관심사의 분리이다.

 

이들은 모두 소프트웨어를 계층으로 분리하였다. 업무규칙에 대한 계층과, 사용자 및 인터페이스를 위한 계층등이 있다. 또한 업무규칙이 아닌 다른 요소와의 독립성도 강조한다. 

  • 프레임워크 독립성: 아키텍처는 프레임워크의 존재 여부에 의존하지 않는다.
  • 테스트 용이성: 업무규칙은 외부요소없이도 테스트가 가능해야 한다.
  • UI 독립성: 업무규칙을 변경하지 않고도, UI를 쉽게 변경할 수 있어야 한다.
  • 데이터베이스 독립성: 업무규칙에 영향을 주지 않고, 데이터베이스를 변경할 수 있어야 한다.

(그림 출처 : Credit: 도서출판 인사이트)


- 의존성 규칙

위의 그림에서 안쪽으로 갈수록 고수준의 소프트웨어다. 앞에서 여러번 강조했듯이 소스코드 의존성은 고수준(다이어그램에서 안쪽원)에 의존해야 한다. 원의 안쪽은 외부에 대해 알지 못하며, 원의 외부는 안쪽에 영향을 주지 않는다.


- 엔티티

엔티티는 핵심 업무규칙을 캡슐화 한다. 메서드를 가진 객체이거나 데이터 구조와 함수의 집합일수도 있다. 엔티티는 다양한 어플리케이션에서 재사용될 수 있을만큼 업무규칙만을 표현해야 하며, 그럴수만 있다면 형태에 너무 집착하지 않아도 된다.


- 유스케이스

이 계층에서는 애플리케이션에 특화된 업무규칙을 포함한다. 애플리케이션에 특화된 업무규칙이기 때문에 엔티티처럼 다양한 어플리케이션을 망라하여 재사용할 가능성은 적다.

 

유스케이스의 변경이 엔티티에 영향을 줘서는 안되며, 원의 외부요소의 변경이 이 계층에 영향을 줘서도 안된다.


- 인터페이스 어댑터

이 계층의 어댑터는 엔티티와 유스케이스의 데이터를 데이터베이스나 웹에 편리한 형식으로 변환한다. 프레젠터, 뷰, 컨트롤러등이 이 계층에 속한다. 컨트롤러에서 유스케이스로 전달되고, 다시 유스케이스에서 프레젠터와 뷰로 되돌아간다.

또한 데이터를 엔티티와 유스케이스에 사용되는 형식에서 영속성(데이터베이스)에 사용되는 형식으로 변환한다.


- 프레임워크와 드라이버

가장 바깥쪽 원인 이 계층에는 일반적으로 데이터베이스나 프레임워크같은 도구들이 위치한다. 이런것들은 모두 세부사항이며 시스템의 주를 이루면 안된다.


- 계층간 횡단

위의 그림에서 오른쪽 하단의 그림을 주목하자. 제어흐름은 컨트롤러에서 시작해 유스케이스, 프레젠터로 흐른다. 그리고 소스코드 의존성은 유스케이스쪽을 가리킨다. 제어흐름과 소스코드 의존성이 반대여야 하는 경우 인터페이스나 상속관계를 적절히 사용하여 의존성 역전 원칙을 이용한다.

 

데이터 측면에서 생각해보자. 계층간을 가로지를때는 DTO(데이터 전송 객체)를 사용한다. 사실 프로젝트를 하다보면 DB에서 반환한 행(Row)를 그대로 가져와서 화면에 뿌리는 행위를 종종볼 수 있다. 이 얘기는 엔티티나 유스케이스계층에서 가장 바깥원인 DB의 데이터구조에 대해 알아야 한다는 얘기가 되므로, 개발 초기단계에서는 이렇게 하면 편하겠지만 프로그램이 점점 복잡해지고나면 SQL만 바꿨는데, View가 변경되는 고통을 맛볼수도 있다.


- 일반적인 시나리오

아래 다이어그램은 DB를 사용하는 웹 기반 자바시스템의 일반적인 시나리오이다.

웹서버 요청을 컨트롤러에서 자바 객체로 변환한 후, InputBoundary 인터페이스를 통해 UserCaseInteractor로 전달한다. 그러면 UserCaseInteractor는 DataAccessInterface를 이용하여 데이터를 불러와 Entities를 완성한다. Entities가 완성되면 자바객체의 Output 데이터를 구성한다. 그러고 나서 OutputBoundary를 이용하여 Presentor로 전달한다.

 

위에서 주목해야 하는건 화살표 방향이다. Package 이름에 가장 안쪽원을 1 번부터 시작해서 숫자를 부여했는데, 항상 바깥쪽 원(높은 숫자)이 안쪽 원(낮은 숫자)에 의존하고 있어 의존성 규칙을 준수한다.


- 결론

소프트웨어를 계층으로 분리하고 의존성 규칙을 준수하면 테스트 하기 쉬운 시스템을 만들 수 있다. 또한 구현 세부사항들(프레임워크 및 데이터베이스)이 변경되더라도 큰 고통없이 변경할 수 있을것이다.

'Concepts > SW Architecture' 카테고리의 다른 글

아키텍처 - 부분적인 경계  (0) 2021.02.10
아키텍처 - 프레젠터와 험블객체  (0) 2021.02.10
아키텍처 - 아키텍처의 오해  (0) 2021.02.10
아키텍처 - 정책과 수준  (0) 2021.02.10
아키텍처 - 경계  (0) 2021.02.10

댓글