You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
한 프로젝트를 구상할 때 개발자가 역할에 따라서 계층을 분리하고 해당 계층에서는 항상 동일한 수준의 업무를 수행하도록 설계한 것이다.
계층화를 통해서 각 계층별 용도를 구별해두었기 때문에 같은 용도끼리 코드를 분리시키고, 다음 하위 계층의 업무를 순서대로 실행한다.
의존성이 상위계층에서 하위로 내려가는 방향을 가지고 있으며 하위에서 상위계층으로의 참조가 일어나지 않도록 해야 한다.
하위계층은 상위계층에서 어떤 로직이 일어나는지 알 수 없습니다.
코드에 수정사항이 생기더라도 계층 간 독립이 명확하게 이루어져 있다면 수정의 범위는 접촉한 계층 간 에서만 이루어진다.
2) 계층형 아키텍처의 장점
- 계층별 의도와 규칙을 지킨다면 계층 간 결합이 느슨하기 때문에 계층 간 종속성이 낮다.
- 종속도가 낮기 때문에 수정이 용이하고, 상-하위로 맞닿아있는 계층만 수정하면 되기 때문에 유지 보수가 쉽고 재사용이 용이하다.
3) 웹 계층형 아키텍처의 구조
- 웹 : 화면단에서의 표현, 유저의 요청이 일어나는 계층
웹 계층에서 요청을 받아서 도메인 혹은 비즈니스 계층에 있는 서비스로 요청을 보낸다.
- 도메인/비즈니스 : 프로젝트에서 사용자에게 제공하고자 하는 서비스에 대한 구현 로직
받은 요청에 대해 필요한 비즈니스 로직을 수행하고, 영속성 계층을 통해 수행 결과에 대한 도메인 엔티티에 접근한다.
- 영속성 : 비즈니스 로직에서 사용하고자 하는 실제 도메인 데이터의 현재 상태를 조회/변경하기 위해 영속성 계층의 컴포넌트를 호출.
도메인 엔티티를 조회/수정하여 데이터를 수정한다.
2. 계층형 아키텍처의 단점
1) 계층형 아키텍처는 데이터베이스 주도 설계를 유도한다.
상단 그림을 보면 의존성의 방향이 가장 상위의 웹 계층은 도메인 계층에 의존하고, 도메인 계층은 영속성 계층에 의존한다.
따라서 영속성 계층이 궁극적으로 바라보고 있는 데이터베이스에 의존하게 된다.
결과적으로 웹 어플리케이션 제작에 쓰이고 있는 계층형 아키텍처의 최종적인 의존성이 데이터 베이스에 있게 된다.
그렇기 때문에 현재 계층형 아키텍처를 사용하고 있는 우리는 데이터베이스를 먼저 설계한 후, 이를 바탕으로 도메인 로직을 구현하는 방식을 자주 사용하고 있다.
계층형 아키텍처에서는 의존성의 방향에 따라 상위에서 하위로 구현하여 결과적으로 데이터베이스에 종속적이게 되기 때문에 합리적인 방식이라고 볼 수 있다.
하지만 비즈니스 관점에서는 위와 같은 방법은 좋지 않다.
사용자에게 제공하고자 하는 서비스를 소프트웨어로 해결하기 위한 규칙과 정책인 도메인을 먼저 설계해야 한다.
상태가 아닌 행동을 중점으로 파악하여 도메인 로직을 가장 먼저 만들고, 로직을 제대로 이해했는지 확인 후 이를 기반으로 영속성 계층과 웹 계층을 만들어야 한다.
데이터베이스 중심적 아키텍처가 만들어지는 가장 큰 원인은 ORM 프레임워크의 사용이다.
도메인 계층에서 영속성 계층에 존재하는 엔티티에 접근하고 사용할 수 있게 되면서 비즈니스 규칙과 영속성 관점을 섞고 싶게 된다.
결과적으로 이러한 접근할 수 있는 자유로 인해서 영속성 계층과 도메인 계층 사이에 강한 결합이 생긴다.
서비스는 영속성모델를 도메인 모델처럼 사용하게 되고 따라서 영속성 계층과 관련된 작업들이 필요해진다.
이러한 결합으로 인해 계층형 아키텍처의 의도나 장점과 다르게 강한 결합성을 가지게 되므로 유연하지 못한 시스템이 되어버린다.
2) 지름길을 택하기 쉬워진다.
계층형 아키텍처에서 어떤 특정 계층은 같은 계층에 있는 컴포넌트나 아래 계층만 접근이 가능하다.
이러한 특성으로 인해 만약 하위에서 상위계층의 컴포넌트에 접근하려고 한다면 아주 쉽게 상위 계층을 하위로 끌어내리는 것이다.
하지만 이러한 행동이 반복되면 해당 프로젝트에서 계층 간 의도나 목적이 모호해지고 점점 의도했던 용도보다 더 많은 기능을 하게 될 것 이다.
특히나 영속성 계층은 가장 하위에 있는 만큼 모든 컴포넌트에 접근이 가능하기 때문에 적절한 계층이 아닌 로직들도 영속성 계층에 존재할 가능성이 높아진다.
3) 테스트하기 어려워진다
앞서 이야기 한 것처럼 계층을 건너뛰는 변화의 형태는 쉽게 일어날 수 있다.
예를 들어 엔티티 하나의 값만을 수정하면 된다고 하면 웹 계층에서 도메인 계층을 생략하고 바로 영속성 계층에 접근하고 싶어 할 수 있다.
이때 두 가지의 문제점이 생긴다.
- 도메인 로직을 웹 계층에 구현한다.
앞으로 더 많은 도메인 로직이 웹 계층에 구현될 가능성이 높아지고, 계층 간 역할 구분이 흐려진다.
또한 이러한 행동으로 인해 도메인 로직이 중복되어 구현되거나 불필요한 코드가 생성될 것이라고 생각합니다.
- 웹 계층 테스트 시 영속성 계층에도 모킹을 해야 한다.
도메인 계층뿐만 아니라 영속성 계층에도 모킹을 하게 되고, 나중에는 다양한 영속성 컴포넌트에 의존성이 많이 쌓이면서 테스트의 복잡도를 높인다.
결과적으로 테스트를 하기 복잡한 조건들로 인해 테스트 자체를 미루는 상황에 직면할 가능성이 높다.
4) 유스케이스를 숨긴다
도메인 로직들이 계층 간 구분을 정확히 지키지 않아서 여러 계층에 존재한다면 새로운 기능을 추가할 위치를 찾기가 어려워진다.
또한 하나의 서비스가 넓은 범위를 포함하고 있으면 특정 유스케이스를 찾기 어려워진다.
뿐만 아니라 영속성 계층에 많은 의존성을 가지게 되고 많은 컴포넌트가 이 서비스에 의존하게 된다.
그러므로 인해 서비스 테스트가 어려워지고 특정 유스케이스를 책임지는 서비스를 찾기도 어려워진다.
5) 동시 작업이 어려워진다.
개발자들이 하나의 계층을 맡아서 작업하는 것이 아니라 하나의 기능을 구현하기 위하여 상위부터 하위까지 여러 계층에 걸쳐서 코드를 작성해야 한다.
같은 서비스를 동시에 편집하는 상황이 발생하기 때문에 conflict에 대한 잠재성을 가지고 있다.