티스토리 뷰
Layered Architecture란
Layered Architecture란 가장 흔한 아키텍처 스타일 중 하나이고, n 티어 아키텍처라 부르기도 합니다.
관심사의 분리를 통해 각 레이어는 자신의 역할에 맞는 책임만을 수행합니다.
Presentation Layer
- 해당 영역은 사용자로부터 입력받은 값들에 대해 유효성 검증을 하고, Business Layer에게 요청을 위임하는 동시에 사용자에게 응답을 반환하는 역할을 수행합니다.
Business Layer
- 해당 영역은 Presentation Layer로부터 전달받은 값을 사용하여 알맞는 요구사항을 만족하는 역할을 수행합니다.
Persistence Layer
- 도메인 엔티티와 매핑하는 역할을 수행합니다.
Infrastructure Layer
- 해당 영역은 Database Layer를 조금 더 포괄적으로 표현하고자 Infrastructure Layer라는 단어를 사용하여 표현하겠습니다. 이 영역은 도메인 엔티티를 데이터베이스에 저장할 수도 있고, Rest API를 사용하여 다른 서비스를 호출할 수도 있고, 메시징 큐를 사용할 수도 있습니다.
레이어 격리
위 그림은 레이어드 아키텍처의 흐름도입니다. 여기서의 각 레이어는 폐쇄 또는 개방 상태입니다.
폐쇄 레이어란 상위 레이어에서 하위 레이어로 이동하므로 중간의 어떤 레이어도 건너뛸 수 없고, 다음 레이어를 거쳐야 비로소 그 다음의 레이어에 진입할 수 있습니다. 이를 fast-lane reader pattern(추월 차선 리더 패턴)이라 합니다.
레이어 격리는 어느 레이어에서 변경이 발생하더라도 다른 레이어에 있는 컴포넌트에 아무런 영향을 미치지 않는 것입니다. 이렇게 레이어 격리가 잘 지켜지기 위해서는 각 레이어간 격리성을 잘 준수할 수 있도록 노력을 기울여야 합니다.
🤔 fast-lane reader pattern에 대한 개인적인 의견
- 읽기 전용 API에 한정하여 Presentation Layer에서 Persistence Layer로 직접적인 접근은 괜찮다고 생각합니다. 그리고 Persistence Layer에서 반환하는 객체가 도메인 엔티티가 아닌 DTO 객체라는 범위 내에서만 한정됩니다.
레이어 개방
위에서는 레이어 격리에 대해 알아보았습니다. 레이어 격리는 이해하기 쉽고, 아 그렇구나! 할 수 있는 부분이 많았습니다. 하지만 레이어 개방에 대해서는 다소 이해하기 어려운 부분이 있습니다. 그렇기 때문에 하나의 상황을 가정하고 살펴보도록 하겠습니다.
예를 들어 어떠한 개발자는 사용자의 요청에 의해 상품의 수량이 감소하는 로직을 구현해야 하는 상황입니다. 그렇기 때문에 개발자는 해당 로직에 접근하기 전에 임계영역을 설정하고 싶어합니다. 이러한 상황에서 레이어를 하나 추가함으로써 해당 요청건만 추가적인 레이어에 접근하고 기존에 있던 다른 요청들은 해당 레이어에 접근을 하지 않도록 하는 것입니다.
아래 그림에서는 수량이 감소하는 요청이 있을 경우 Facade Layer에서 Lock을 획득하고 Business Layer로 넘어가는 것입니다. 그렇지 않은 경우에는 굳이 Facade Layer를 지나칠 필요가 없기 때문에 Business Layer에 접근하는 것입니다. 이때 Facade Layer는 상황에 따라 지나칠 수 있어야 하므로 항상 공개된 상태를 가지는 Layer가 됩니다.
Infrastructure Layer에 직접 접근하는것을 최소한으로 하자
만약 사용자가 파일 업로드를 한다고 가정을 해봅시다. 이때 사용자는 AWS 버킷에 파일을 업로드 하거나 NCP, GCP의 버킷에 업로드를 할 수 있습니다. 아래 그림은 사용자가 파일을 업로드 하는 과정을 간단히 그린 예시입니다.
말하고자 하는 것은 Business Layer에서 Infrastructure Layer에 접근할 때 Infrastructure Layer에 구현되어 있는 구체 클래스에 직접적으로 접근을 하는 경우입니다. 만약 이렇게 된다면 Infrastructure Layer에 구현된 구체 클래스에서 변경이 발생했을 경우 영향이 미치는 범위는 Business Layer까지입니다.
💡 어떻게 해결할 수 있을까?
- 파일을 업로드 하는 행위는 어디에 업로드할지 Business Layer가 알 필요가 없습니다. 또한 상황에 따라 AWS, NCP, GCP 다양한 버킷에 업로드가 될 수 있기 때문입니다. 이때 인터페이스를 활용하여 해당 문제를 해결할 수 있습니다.
Layered Architecture의 주의사항
🧨 아키텍처 싱크홀 안티패턴
- 이 안티패턴은 사용자의 요청이 각 레이어에서 다른 레이어로 이동할 때 각 레이어에서 아무런 비지니스 로직도 처리하지 않고 그냥 지나쳐가는 안티패턴입니다.
- 해당 안티패턴의 단점으로는 쓸때없는 자원을 소모합니다. Spring을 사용한다면 사용자의 요청이 왔을 때 하나의 Thread가 해당 요청을 수행하게 되는데 Thread의 CallStack에 의미가 없는 stack이 하나 더 추가됩니다.
💡 해결방안
- 아키텍처 싱크홀 안티패턴으로 처리 중인 요청의 전체 비율을 파악하는 것이 중요합니다. 80 대 20 법칙을 적용해서 전체 요청의 20%가 싱크홀인 정도면 괜찮은 수준입니다. 그러나 반대로 80%가 싱크홀이라면 문제가 있는 상황입니다. 이때는 레이어드 아키텍처가 적합하지 않다는 증거입니다. 즉 다른 아키텍처를 고민해야 합니다.
- 모든 레이어를 개방합니다. 그러나 개방했다는 것은 응집도를 낮아지고 결합도가 높아지므로 트레이드오프를 해야합니다.
- 개인적인 생각으로 아키텍처 싱크홀 안티패턴은 읽기 API가 요청한 작업을 단순 serving하므로 fast-lane reader pattern을 적용하여 해결할 수 있지 않을까? 생각합니다.
Layered Architecture의 장단점
장점
- 도메인이 복잡하지 않은 경우 적절합니다.
- 각 레이어를 통해 일관성을 지킬 수 있습니다.
단점
- 프로젝트의 규모가 커질수록 관리하기 어렵고 확장성이 떨어집니다.
- 레이어로 분리된 관심사를 제외한 다른 관심사가 발견되는 경우 패키지 분리나 적절한 코드 배치가 어렵습니다.
참고
- http://improvedesignpatterns.blogspot.com/2010/06/fast-line-reader-or-fast-lane-reader.html
- https://msolo021015.medium.com/layered-architecture-deep-dive-c0a5f5a9aa37
- https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html
- https://priyalwalpita.medium.com/software-architecture-patterns-layered-architecture-a3b89b71a057
- https://dzone.com/articles/layered-architecture-is-good
- https://medium.com/riiid-teamblog-kr/gradle%EA%B3%BC-%ED%95%A8%EA%BB%98%ED%95%98%EB%8A%94-backend-layered-architecture-97117b344ba8
'Architecture' 카테고리의 다른 글
Event Driven Architecture (0) | 2023.09.16 |
---|---|
Service Based Architecture (0) | 2023.09.13 |
Microkernel Architecture (0) | 2023.09.09 |
PipeLine Architecture (0) | 2023.09.07 |
CQRS 패턴 (0) | 2023.01.14 |
- Total
- Today
- Yesterday
- spring boot redisson 분산락 구현
- pipeline architecture
- spring boot redisson sorted set
- transactional outbox pattern spring boot
- microkernel architecture
- spring boot excel download paging
- transactional outbox pattern
- 서비스 기반 아키텍처
- 레이어드 아키텍처란
- 트랜잭셔널 아웃박스 패턴 스프링부트
- spring boot 엑셀 다운로드
- 공간 기반 아키텍처
- spring boot redisson destributed lock
- spring boot excel download oom
- redis 대기열 구현
- @ControllerAdvice
- space based architecture
- 람다 표현식
- java userThread와 DaemonThread
- java ThreadLocal
- spring boot redis 대기열 구현
- 트랜잭셔널 아웃박스 패턴 스프링 부트 예제
- pipe and filter architecture
- redis sorted set으로 대기열 구현
- redis sorted set
- 자바 백엔드 개발자 추천 도서
- polling publisher spring boot
- service based architecture
- spring boot poi excel download
- JDK Dynamic Proxy와 CGLIB의 차이
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |