Layered Architecture
왜 Layered Architecture를 선택하는가
  • backend

시작하며

나는 프로젝트를 생성할 때 일반적으로 Layered Architecture로 폴더를 구성하는 편이다.
그렇다면 Layered Architecture는 무엇이고 또 어떻게 사용하는건지 정리해보고자 한다.

다음 중 1개라도 해당한다면 읽어보는것을 추천한다.

  1. 하나의 Endpoint안에 모든 코드를 집어넣는 사람
  2. Layered Architecture를 알아보고싶은 사람
  3. Spring boot (Java), Nest.js (Node) 에서 왜 controller, service, repository 의 폴더가 구분되어 있는지 궁금한 사람
  4. 자신이 (혹은 팀이) 만들고있는 프로젝트가 점점 거대해지고 프로젝트를 관리하는 개발자가 많아지는 경우

Layered Architecture

image

4개의 Layer로 구분되는 아키텍쳐이다. (설명하는 글마다 조금씩 차이는 있을 수 있다)
화살표의 방향이 그려진 것 처럼 상위에서는 하위 Layer를 참조하지만(Dependency가 있지만) 하위에서 상위 Layer를 참조할 수 없다. (일방향)

이렇게 Layer를 구분하는 가장 큰 이유는 관심사의 분리를 통해 본인의 역할에만 집중하고 책임을 다하기 위함이다.

그리고 이를 통해 얻을 수 있는 장점으로는
시스템의 결합도를 낮추고 응집도가 높아진다. 그러면서 한 명의 개발자가 모든 도메인에 대해 알아야 할 필요가 없어지고 코드의 재사용성을 높이고 유지보수성을 확장할 수 있다. 마지막으로는 Layer의 분리를 통해 각 함수의 크기가 줄어들고 본인의 역할과 책임이 분명해지면서 테스트가 용이해지는 장점이 있다.

각각 레이어의 역할

Presentation

사용자의 요청을 바로 받는 Layer이다. Request와 Response를 처리한다.

HTTP에 의존성을 가지고있는 Layer로 Request로부터 넘어온 값을 뽑아내어 타입체크등을 처리하고 Application으로 전달한다. 그리고 Application로 부터 전달받은 결과값을 Response를 통해 응답을 반환하는 역할을 한다.

Application

Presentation LayerDoamin Layer를 연결해주는 역할을 한다.
최소한의 정보만을 가지는것이 특징이며 transaction관리, DTO변환, 모듈간 연계의 역할을 한다.

외부 시스템에 의존성을 가지지는 않지만 여러 Domain에 의존성을 가진다.
도메인끼리 호출하는경우 순환참조를 방지하기위해 Application에서 여러 Domain에서 데이터를 가져오는 역할을 한다. 그 중에 필요하다면 transaction으로 여러 Domain을 호출하기도 한다.

Domain

실제 비지니스 도메인에 대한 코드가 위치한다. 해당 도메인에 대한 모든 책임을 가진다.

Application Layer와 마찬가지로 외부 시스템에는 의존성을 가지지 않는다. 해당 Domain에 대한 비지니스 핵심 로직이 포함되어있으며 Infra Layer로부터 데이터를 호출하는 역할을 한다.

Domain Layer를 설계할 때 DI (Dpendency Injection)방식을 사용하면 테스트에 더욱 용이하고 Domain Layer에는 외부 의존성을 가지지 않도록 주의해야 한다.

Infra

상위계층을 지원하는 Layer로 외부 시스템과 연결하여 데이터를 가져오는 역할을 한다.

DB 데이터에 Access하거나 그 밖의 메일발송, 보안, Queue 등에 접근하여 데이터를 전송하거나 조회하는 역할을 한고 외부 시스템에 의존성을 가지는 Layer이다.

Layered Architecture의 단점

지금까지 Layered Architecture의 각 Layer에 대해 알아보고 사용했을 때 장점에 대해 알아봤다. 그렇다면 단점은 없을까?

  • Layer구분으로 인해 폴더 구조가 복잡해진다.
  • 규모가 비교적 작은 프로젝트에서 복잡한 폴더구조가 오히려 개발 생산성을 떨어뜨릴 수 있다.
  • 폴더 구조가 복잡해지는것에 비해 성능적인 이점을 얻기는 어렵다.

참조