서비스에서는 필요한 비즈니스 로직을 수행하고, 도메인 엔티티의 현재 상태를 조회하거나 변경하기 위해영속성 계층의 컴포넌트를 호출
사실 계층형 아키텍처는 견고한 아키텍처 패턴이다
계층을 잘 이해하고 구성한다면 웹 계층이나 영속성 계층에 독립적으로 도메인 로직을 작성할 수 있음
도메인 로직에 영향을 주지 않고 웹 계층과 영속성 계층에 사용된 기술을 변경 가능
잘 만들어진 계층형 아키텍처는 선택의 폭을 넓히고, 변화하는 요구 사항과 외부 요인에 빠르게 적응할 수 있음
계층형 아키텍처의 함정
계층형 아키텍처는 데이터베이스 주도 설계를 유도한다
우리가 만드는 대부분의 애플리케이션의 목적은 보통 비즈니스를 관장하는 규칙이나 정책을 반영한 모델을 만들어서 사용자가 이러한 규칙과 정책을 더욱 편리하게 활용할 수 있게 하는 것. 즉, 비즈니스 로직이 중심이 되어야 함
정의에 따르면 전통적인 계층형 아키텍처의 토대는 도메인 로직이 아닌 데이터베이스
의존성 방향이 ‘웹 계층 → 도메인 계층 → 영속성 계층’ 이기 때문에 자연스레 데이터베이스에 의존
데이터베이스의 구조를 먼저 생각하고, 이를 토대로 도메인 로직을 구현하는 방식은 전통적인 계층형 아키텍처에서는 합리적인 방법
하지만 이는 비즈니스 관점에서는 전혀 맞지 않는 방법이다
다른 무엇보다도 도메인 로직을 먼저 만들어야 하고, 도메인 로직이 맞다는 것을 확인한 후에 이를 기반으로 영속성 계층과 웹 계층을 만들어야 한다
데이터베이스 중심적인 아키텍처가 만들어지는 가장 큰 원인은 ORM 프레임워크를 사용하기 때문
ORM 프레임워크와 계층형 아키텍처를 결합하면 비즈니스 규칙이 영속성 관점과 섞이기 쉬움
ex) 도메인 계층에서 영속성 계층의 엔티티에 접근
즉, 서비스는 영속성 모델을 비즈니스 모델처럼 사용하게 되고 이로 인해 도메인 로직 뿐만 아니라 영속성 계층과 관련된 작업들을 하게됨 → 영속성 계층과 도메인 계층 사이에 강한 결합이 형성됨
지름길을 택하기 쉬워진다
전통적인 계층형 아키텍처에서 전체적으로 적용되는 유일한 규칙은, 특정한 계층에서는 같은 계층에 있는 컴포넌트나 아래에 있는 계층에만 접근 가능하다는 것
문제는 이러한 규칙을 지키기 위해 다음과 같은 지름길(꼼수)을 택하기 쉬움
상위 계층에 위치한 컴포넌트에 접근하기 위해 컴포넌트를 계층 아래로 내려버림 (ex : 헬퍼, 유틸리티 컴포넌트)
시간이 지날수록 팀원 대부분 이러한 지름길을 택하게 되고(깨진 창문 이론), 영속성 계층은 점점 비대해지며 책임이 혼재됨
테스트하기 어려워진다
자주 발생하는 지름길의 예로는 웹 계층에서 바로 영속성 계층에 접근하는 것
ex) 엔티티의 필드를 단 하나만 조작하는 경우
도메인 로직을 웹 계층에 구현하게 되면 발생하는 문제점
애플리케이션 전반에 걸쳐 책임이 섞이고 핵심 도메인 로직들이 퍼져나갈 확률이 높음
웹 계층 테스트 시 도메인 계층 뿐만아니라 영속성 계층도 모킹해야 함 → 단위 테스트의 복잡도 증가 → 테스트 코드 작성보다 종속성을 이해하고 모킹하는데 오랜 시간 소요 → 테스트 작성 포기
유스케이스를 숨긴다
개발자들은 실제로 새로운 코드를 짜는 시간보다 기존 코드를 바꾸는 데 더 많은 시간을 소요함
그렇기에 아키텍처는 코드를 빠르게 탐색하는 데 도움이 돼야 함
계층형 아키텍처는 앞서 논의했듯이 도메인 로직이 여러 계층에 걸쳐 흩어지기 쉬움
도메인 계층을 생략하고 웹 계층에 로직 작성
도메인 계층과 영속성 계층 모두에서 접근할 수 있도록 특정 컴포넌트를 아래로 내림
계층형 아키텍처는 도메인 서비스의 ‘너비’에 관한 규칙을 강제하지 않아 여러 유스케이스를 담당하는 아주 넓은 서비스가 만들어지기도 함
넓은 서비스는 영속성 계층에 많은 의존성을 갖게 되고, 다시 웹 레이어의 많은 컴포넌트가 이 서비스에 의존함 → 테스트 작성이 힘들어지고, 작업해야 할 유스케이스를 책임지는 서비스를 찾기도 어려움
동시 작업이 어려워진다
프로젝트에 인원이 더 투입되어 개발이 빨라지려면 아키텍처가 동시 작업을 지원해야 함
하지만 계층형 아키텍처는 이런 측면에서는 그다지 도움이 되지 않음
하나의 유스케이스를 3명이서 웹 계층, 도메인 계층, 영속성 계층을 담당? 계층형 아키텍처에서는 어려움 모든 것이 영속성 계층 위에 만들어지기 때문에 영속성 계층이 먼저 만들어져야 하고, 그다음 도메인, 그다음 웹 계층을 만들어야 함. 그렇기에 특정 기능은 동시에 한명의 개발자만 작업할 수 있음
서로 다른 유스케이스에 대한 작업을 동시에 하는 경우도 같은 서비스를 동시에 편집하는 상황이 발생하고, 이는 병합 충돌과 잠재적으로 이전 코드로 되돌려야 하는 문제를 야기
정리
올바르게 구축하고 몇 가지 추가적인 규칙들을 적용하면 계층형 아키텍처는 유지보수하기 매우 쉬워지며 코드를 쉽게 변경하거나 추가할 수 있다
하지만 계층형 아키텍처는 많은 것들이 잘못된 방향으로 흘러가도록 용인한다(강제하지 않는다)
아주 엄격한 자기 훈련 없이는 시간이 지날수록 품질이 저하되고 유지보수하기 어려워진다
계층형 아키텍처로 만들든 다른 아키텍처 스타일로 만들든,계층형 아키텍처의 함정을 염두에 두면 지름길을 택하지 않고 유지보수하기에 더 쉬운 솔루션을 만드는 데 도움이 될 것이다.