본 시리즈는 "만들면서 배우는 클린 아키텍처"(톰 홈버그 저)의 책으로 공부하며 정리한 내용을 담고있습니다.

맨날 레거시 코드 개편만 하다가 정말 뒤늦게 클린 아키텍처라는 개념을 접하게 되었다.
내가 하고있는 개발과는 너무나도 다른 방식, 처음 구조 잡는게 어렵지 장점이 훨씬 많은 아키텍처임을 알게되면서 조금 더 자세히 알아보고 싶어졌다.
해당 책은 이미 유명한 개발서적 중 하나로 알려져있는 책으로.. 아키텍처 공부할 때 추천 목록에서 빠지지 않는 책이다.
얇아서 부담스럽지 않게 읽기 좋은 책인 것 같다.
전통적인 웹 애플리케이션은 웹계층, 도메인 계층, 영속성 계층으로 구성되어있다.

웹 계층에서는 요청을 받아 도메인 혹은 비즈니스 계층에 있는 서비스로 요청을 보낸다.
서비스에서는 필요한 비즈니스로직 수행, 도메인 엔티티의 현재 상태를 조회하거나 변경하기 위해 영속성 계층의 컴포넌트를 호출한다.
잘 만들어진 계층형 아키텍처는 선택의 폭을 넓히고, 변화하는 요구사항과 외부 요인에 빠르게 적응할 수 있게 해준다.
필자는 계층형 아키텍처가 코드에 나쁜 습관들이 스며들기 쉽게 만들고, 시간이 지날 수록 소프트웨어를 점점 더 변경하기 어렵게 만드는 수많은 허점을 가지고 있다고 한다.
데이터 베이스의 구조를 먼저 생각하고 이를 토대로 도메인 로직을 구현한 경험이 있을것이다.
위의 이미지대로 모든것은 영속성 계층을 토대로 만들어지고 의존성의 방향에 따라 자연스럽게 '도메인 로직'이 아닌 '데이터베이스'를 토대로 아키텍처를 구현해왔다.
이는 비즈니스 관점에서는 전혀 맞지 않는 방법이며 도메인 로직을 먼저 만들어야한다.
그래야만 로직을 제대로 이해했는지 확인할 수 있으며, 도메인 로직이 맞다는 것을 확인한 후에 이를 기반으로 영속성 계층과 웹 계층을 만들어야한다.
데이터 베이스 중심적인 아키텍처가 만들어지는 원인은 ORM(Object-Relational-Mapping)프레임워크를 사용하기 때문이다.
ORM에 의해 관리되는 엔티티들은 일반적으로 영속성 계층에 두고, 계층은 아래 방향으로만 접근 가능하기 때문에 도메인 계층에서는 엔티티에 접근할 수 있다.
이렇게 되면 영속성 계층과 도메인 계층 사이에 강결합이 생긴다.
서비스는 영속성 모델을 비즈니스 모델처럼 사용하게 된다.
이로 인해 도메인 로직뿐만 아니라 영속성 계층과 관련된 작업(즉시로딩(eager loading), 지연로딩(lazy loading), 데이터베이스 트랜잭션, 캐시 플러시등등..)을 해야한다.
👉🏻 유연하고 선택의 폭을 넓혀준다던 계층형 아키텍처의 목표와 정확히 반대되는 상황!!
전통적인 계층형 아키텍처에서 전체적으로 적용되는 유일한 규칙은, 특정 계층에서는 같은 계층에 있는 컴포넌트나 아래에 있는 계층만 접근 가능하다는 것이다.
따라서 상위 계층에 위치한 컴포넌트 접근을 위해선 컴포넌트를 계층 아래로 내리면 되는데 이런식의 개발이 계속되면 영속성 계층은 컴포넌트르 아래 계층으로 내릴수록 비대해진다.
계층형 아키텍처를 사용할 때 일반적으로 계층을 건너뛰는 형태로 변화한다.
하지만 이런 일이 자주 일어난다면 두 가지 문제점이 생긴다.
👉🏻 시간이 흘러 웹 컴포넌트의 규모가 커지면 다양한 영속성 컴포넌트에 의존성이 많이 쌓이며 테스트의 복잡도를 높인다.
실제로 테스트 코드를 작성하는 것 보다 종속성을 이해하고 목(mock)을 만드는 데 더 많은 시간이 걸리게 된다.
개발자들은 기능을 추가하거나 변경할 적절한 위치를 찾는 일이 빈번하기 때문에 아키텍처는 코드를 빠르게 탐색하는 데 도움이 되어야 한다.
하지만 계층형 아키텍처에서는 도메인 로직이 여러 계층에 걸쳐 흩어지기 쉽고, 유스케이스가 간단해서 도메인 계층을 생략한다면 웹 계층에 존재할 수도, 도메인 계층과 영속성 계층 모두에서 접근할 수 있도록 특정 컴포넌트를 아래로 내렸다면 영속성 계층에 존재할 수도 있다.
이럴 경우 새로운 기능을 추가할 적당한 위치를 찾는 일이 어렵다. 넓은 서비스는 영속성 계층에 많은 의존성을 갖게되고, 다시 웹 레이어의 많은 컴포넌트가 이 서비스에 의존하게 된다.
👉🏻 서비스를 테스트하기도 어려워지고 작업해야 할 유스케이스를 책임지는 서비스를 찾기도 어려워진다.
적절한 규모의 프로젝트에서는 인원이 더 투입될 경우 개발이 빨라진다고 생각할 수 있다.
그렇게 되려면 동시 작업을 지원해야하지만 계층형 아키텍처는 이런 측면에서 도움이 되지 않는다.
ex) 애플리케이션에 새로운 유스케이스를 추가하려고 한다.
세 명의 개발자가 웹 계층, 도메인 계층, 영속성 계층에 각각 기능을 추가할 수 있을까?
계층형 아키텍처에서는 모든 것이 영속성 계층 위에 만들어지기 때문에 영속성 계층을 먼저 개발해야 하고, 그 다음에 도메인 계층, 마지막으로 웹 계층을 만들어야한다.
그렇기 때문에 특정 기능은 동시에 한 명의 개발자만 작업할 수 있다.
Q. 인터페이스를 먼저 같이 정의하고 작업하면 되지 않을까?
A. 물론 가능하지만 데이터베이스 주도설계를 하지 않는 경우에만 가능하다.
데이터베이스 주도 설계는 영속성 로직이 도메인 로직과 너무 뒤섞여서 각 측면을 개별적으로 작업할 수 없다.
코드에 넓은 서비스가 있다면 서로 다른 기능을 동시에 작업하기 더욱 어렵다.
같은 서비스를 동시에 편집하는 상황이 발생하면 병합충돌(merge conflict)이 생기고, 잠재적으로 이전 코드로 되돌려야하는 문제를 야기한다.
출처 : 만들면서 배우는 클린아키텍처