본문 바로가기
Develop/Design

[Clean Architecture] 계층형 아키텍처의 문제점

by 코딩의성지 2022. 4. 10.

최근에 "만들면서 배우는 클린 아키텍처"라는 책을 정독했다.

요즘 웹 아키텍처에서 한번쯤은 들어보셨을 "헥사고날(육각형) 아키텍처에 대한 내용을 알차게 알려주는 책인데, 시간나면 한번쯤 읽어보시길 권해드린다.

 

오래오래 기억하고 싶어 블로그에 한 챕터씩 중요하다 생각되는 내용들을 정리해볼까한다.

오늘은 1 챕터의 "계층형 아키텍처의 문제는 무엇일까?" 에 대한 내용을 정리해보겠다.

 

계층형 아키텍처는 아직도 많이 사용되는 아키텍처 방식이다. 심지어 지금 근무하고 있는 회사에서도 이 아키텍처 방식을 사용하고 있다.

 

1. 계층형 아키텍처는 데이터베이스 주도 설계를 유도한다.

웹 - 도메인 -영속성 계층으로 이루어진 계층형 아키텍처에서는 결국 웹계층은 도메인에, 도메인 계층은 영속성에 의존하기 때문에 결국 데이터베이스에 의존하게 된다.

데이터베이스를 중심으로 아키텍처를 만드는 방식은 전통적인 계층형 아키텍처에서는 합리적인 방법이었으나, 비지니스적인 관점에서는 전혀 맞지 않는 방법이다.

 

객체지향 설계를 위해서는 도메인 로직 중심으로 설계를 진행해야 한다. 도메인 로직을 만들고 검증한 뒤에, 이를 기반으로 영속성 계층과 웹계층을 만드는 것이 올바른 방향이다.

 

ORM(Object-Relational mapping) 기술을 활용하다 보면, 이런 데이터베이스 중심의 아키텍처를 더욱더 쉽게 만들곤 한다. ORM 프레임워크가 계층형 아키텍처에서 영속성 관점과 비지니스 규칙을 섞기 딱 좋게 기능 들을 제공하기 때문이다.

 

 

보통 ORM 에서는 엔티티를 영속성 계층에 포함시키는데 이렇게 두면 영속성 계층과 도메인 계층에 강한 결합이 발생한다. 즉 도메인 계층에서 비지니스 로직 뿐만 아니라, eager loading/ lazy loding 에 대한 처리, 트랜잭션, 캐시 플러시 등 영속성과 관련된 작업들도 추가로 해줘야하는 문제가 생긴다.

 

2. 지름길을 택하기 쉬워진다.

계층형 아키텍처에서는 같은 계층이나 아래 계층에만 접근이 가능하다. 그런데 개발을 하다보면 상위 계층에 위치한 컴포넌트에 접근해야할 때가 있다. 이때 흔히 개발자들이 하는 방법은 .. 접근할 컴포넌트를 계층 아래로 내려버린다. 굉장히 쉬운방법이다. 한번이 어렵지 두번 세번은 쉽다. 심리학에서는 이러한 이론을 "깨진 창문 이론"이라고 부른다.

 

시간이 지나면 아키텍처는 아래그림과 같이 될 확률이 농후하다.

 

헬퍼 컴포넌트나 유틸리티 컴포넌트는 객체지향 진영에서는 피해야할 방식 중에 하나인데, 심지어 각 계층에 전혀 포함되지 않을 것처럼 보이는 이러한 컴포넌트들이 영속성 계층에 포함되어 있으니 계층이 점점 비대해지고 비효율적으로 변해간다.

 

3. 테스트가 어려워진다.

계층형 아키텍처에서 개발하다 보면 웹계층에서 바로 영속성 계층의 엔티티에 접근해서 조작하면 되지 않을까하는 생각이 든다. 엔티티 필드 한두개만 조작하면 되는 경우라면 굳이 도메인 계층을 통해서 할 필요가 없다는 생각이 들 것이다.

아까 말했듯이 이런건 한번이 어렵지 그이후는 굉장히 쉽다. (깨진 창문 이론)

 

하지만 이렇게 하면 2가지 문제가 생긴다.

 

첫째는 아무리 간단한 로직이더라도 도메인 로직이 웹 계층에 구현되게 된다는 것이다. 아주 작은 단위의 프로젝트에서는 괜찮지만 점점 확장하게 될 서비스라면 이렇게 짜 놓으면 어플리케이션 전반에 책임이 뒤섞여 버리고 핵심 도메인로직이 웹 계층에 중구난방 구현되게 될 것이다.

 

두번째 문제는 테스트 시에 도메인 계층 뿐만아니라 영속성 계층의 컴포넌트들도 모킹해줘야한다는 것이다.

이렇게 되면 테스트의 복잡도가 올라가게 되어 정상적인 단위테스트가 불가능해진다. (목킹 객체를 만드는 것도 굉장히 많은 시간이 소요되는 작업이라는 것을 꼭 기억하길 바란다.)

 

4. 유즈케이스를 숨긴다.

프로젝트시 설계를 제대로 진행하는 이유는 추후에 기능을 추가하거나 변경할때 적절한 위치를 빠르게 찾기 위해서 이다. 이런 측면에서 계층형 아키텍처는 상당히 불리하다. 계층형 아키텍처는 여러 계층에 도메인 로직이 흩어져 있을 가능성이 굉장히 높다. 이렇게 되면 새로운 기능을 추가할때 그 위치를 찾는게 굉장히 어려워진다.

 

그리고 계층형 아키텍처는 도메인 서비스가 비대해지는 것에 대해 강제로 막지 않는다. 시간이 지나면 서비스 컴포넌트가 아래 그림처럼 굉장히 비대해져 버릴수도 있다.

 

 

비대한 서비스는 영속성 계층에 많은 의존성을 가지게 되고, 반대로 웹 계층의 많은 컴포넌트가 이 서비스의 의존하게 된다. 이렇게 되면 해당 서비스는 테스트하기도 어렵고 추후에 추가해야할 기능에 대한 유즈케이스에 대한 책임지는 서비스를 찾기도 힘들어진다.

 

5. 동시 작업이 어려워진다.

투입된 인원들이 각자가 맡은 모듈을 개개인들이 개발하면 참으로 좋겠지만 현실적으로 쉽지 않다. 결국 프로젝트는 서로 도움을 주고 받으며 개발된다. 이러한 환경에서 계층형 아키텍처는 동시작업이 쉽지가 않다.

 

가능하다고 생각하는사람들도 있을수 있다. 만약 개발자 세명이 있다고 치면 한명은 웹, 한명은 도메인, 한명은 영속성 계층을 작업하면 되는거 아닌가 생각할 수도 있다.

하지만 계층형 아키텍처에서는 이렇게 작업하는 것을 불가능하다. 모든 것이 영속성 계층 위에서 만들어지기에 가장 먼저 영속성 계층을 개발해야하고, 그다음은 도메인을, 그리고 나서 웹을 개발해야 한다. 하나의 기능을 만들때에는 한명의 개발자만 개발이 가능한 구조라는 말이다.

 

그렇다고 서로 다른 기능을 맡아서 개발하는 것도 쉽지 않다. 다른 유즈케이스를 개발하다보면 같은 서비스를 동시에 편집하는 상황이 발생하는데 이는 소스코드가 conflict 나기 딱 좋은 상황이다. 하루종이 컨플릭트를 제거하는데 시간을 쓰는 경험을 할 수 있을 것이다.

 

오늘은 계층형 아키텍처의 문제점에 대해 포스팅해봤는데, 다음에는 의존성역전을 통해 문제를 해결하는 방법을 포스팅해보도록 하겠다. 끝!

 

Ref.
톰 홈버그, 『만들면서 배우는 클린 아키텍처』, 위키북스(2021), p1~11

반응형

댓글