본문 바로가기
Architecture

[Spring] Layered-Architecture(계층형 아키텍처)

by doodoom 2023. 4. 14.

0. 이 글을 쓰게된 이유

Spring을 사용하면 Layered-Architecture를 사용하게 된다. Layered-Architecture의 컨셉에 대해서 확실하게 정리하기 위해 이 글을 쓰데 되었다.

1. Layered-Architecture란?

Layered-Architecture는 사실 상의 Java EE 표준인만큼 가장 널리 사용되고 유명한 아키텍처 패턴이다. 다른 말로 N-tier Architecture이라고 불린다.

Layered-Architecture의 각 계층은 수직적인 구조를 가지고있다. 각각의 계층은 특정 역할을 가지게 된다(예 -> presentation 로직, business로직). 하지만 계층의 개수나 역할은 정해져 있지않다. 구조를 설계하는 사람이 정하기 나름이다. 보통의 경우에는 4 계층 : presentation, business, persistence, database를 구조가 가장 흔하게 사용된다.

1.1 4계층 구조

4계층 구조에서 각각의 계층은 다음과 같은 역학을 가진다.

1.1 Presentation Layer(표현 계층)

Presentation Layer는 클라이언트에게 보여지는 부분과 소통 로직을 책임진다. 이 계층은 비즈니스 로직은 어떻게 처리되는지, 어디에서 데이터를 가져오는지에 대한 관심이 없다. 웹에서는 보통 html이나 json 같은 형식을 사용자에게 보여준다.

1.2 Business Layer(비즈니스 계층)

Business Layer는 비즈니스 로직을 수행하는 것에 책임을 진다. 이 계층은 클라이언트에게 어떻게 뿌려지는지, 어디에서 데이터를 가죠오는지에 대한 관심이 없다. 개인적으로는 이 Layer는 어떻게 구현되던 POJO로 구현 되어야한다고 생각한다.

1.3 Persistence Layer(영속성 계층)

Persistance Layer는 어플리케이션의 영속성을 구현하는 것에 책임을 진다. 데이터가 어디에서 오는지, 어떻게 오는지에 대한 로직을 담당한다.

1.4 Database Layer(데이터베이스 계층)

데이터베이스 계층을 의미한다.

위는 가장 흔하게 쓰이는 것이지 꼭 저렇게 쓰여야하는 것이 아니다. 프로젝트에 효율적이고 설득력 있는 구조라면 모두 괜찮다.

2. Layered-Architecture 핵심 컨셉

Layered-Architecture에서 가장 중요한 컨셉은 각 계층끼리 닫혀있다는 것이다. 닫혀있다는 것이 소통을 안한다는 의미가 아니라, 요청이 계층 간에 이동할 때 해당 계층 아래의 다음 계층으로 이동하려면 해당 계층 바로 아래의 계층을 통과해야 함을 의미합니다. 링크드 리스트처럼 1에서 3으로 가려면 1 -> 2 -> 3 같은 형식으로 가야함을 의미한다.

그렇다면 왜 꼭 그래야할까? 예를 들어 presentation 계층에서 바로 persistence 계층으로 가서 데이터를 가져오는 것이 더 빠르고 효율적일 수 있지않을까? 이에 대한 답은 계층의 독립성이라는 핵심 개념에 답이 있다.

2.1 계층의 독립성

이 개념의 핵심은 한 계층에서의 변경이 다른 계층에 최대한 영향을 미치지 않아야한다에 있다. 만약 presentation 계층에서 바로 persistence 계층으로 가서 데이터를 가져오게 되면 persistence 계층의 변경이 presentation, service 두 계층에 영향을 미치게된다. 그렇다면 변경이 굉장히 힘들 수 있다.

물론 폐쇄형 계층보다 개방형 계층이 더 효과적인 경우가 있다. 개방형 및 폐쇄형 계층의 개념을 활용하면 아키텍처 계층과 요청 흐름 간의 관계를 정의하는 데 도움이 되며 설계자와 개발자에게 아키텍처 내의 다양한 계층 액세스 제한을 이해하는 데 필요한 정보를 제공한다. 아키텍처에서 개방형 및 폐쇄형 계층(및 그 이유)을 문서화하거나 적절하게 전달하지 못하면 일반적으로 테스트, 유지보수 및 구현이 매우 어려운 긴밀하게 결합되고 취약한 아키텍처가 발생한다.

4. Layered-Architecture의 장점

4.1 관심 분리

마틴 파울러는 layer를 나누는 것의 최대 장점은 작업 대상인 layer에만 집중할 수 있도록 도와준다는 점이라고 얘기한다. 하지만 실제로 한 layer의 변경은 다른 layer의 변경을 초래하지만 그럼에도 layer가 나누어져있는게 집중하기에 편하다고 한다.
관심 분리는 객체의 의존성 분리와 모듈화에서도 얻을 수 있지만, layer를 나누게 되면 더 거대한 범위인 layer 단계에서 책임 분리를 할 수 있게 된다.

4.2 모듈화

layer를 통해 해당 계층의 역할을 모듈화 하므로, 갈아끼우기에 용이하다.
추상화가 잘 된 경우, 부품 갈 듯이 갈아끼는 것이 가능하다.
예를 들어, 각 layer에 추상화가 잘 이루어지면 domain 로직의 중복 없이 여러 presentation을 구현 가능하다. 같은 domain 로직을 사용하며 app, web, console application을 모두 구현이 가능하다. data access 계층도 RDBMS를 사용하다가 NoSql로 변경하는 등의 변경이 용이하다.

4.3 테스트 용이

layer를 나누게 되면 자연스럽게 테스트하기 용이하게 된다.
보통 presentation layer는 테스트하기 까다롭기 때문에 도메인 로직에 최대한 많은 로직을 넣어 테스트를 가능하게 할 수 있다. 그리고 data access layer를 테스트하려면 많은 자원과 시간을 잡아먹기 때문에 이 계층을 test double을 통해 쉽게 테스트할 수 있다.

5. Layered-Architecture 설계 시 주의할 점

5.1 Architecture Sinkhole Anti-Pattern

Architecture Sinkhole Anti-Pattern은 계층 간에 요청이 이동할 때, 어떤 계층은 로직이 너무 단순하거나 없어서 다른 계층으로 연결만 해주는 경우를 뜻한다. 이러한 흐름은 리소스 낭비를 초래할 수 있다. 하지만 프로젝트를 하다보면 이런 경우가 종종 생긴다. 프로젝트 내에서 이런 경우가 20%이하라면 괜찮은 구조라고 한다.

'Architecture' 카테고리의 다른 글

[Architecture] Service Layer의 역할  (0) 2023.04.18