레이어드 아키텍처(Layered Architecture)가 무엇인지 알아보자.
소프트웨어 아키텍처란?
소프트웨어 아키텍처란, 소프트웨어 시스템의 전체적인 구조와 구성요소들 간의 상호작용을 설계하는 것을 말한다.
쉽게 말해, 건축물의 뼈대를 잡는 것과 같은 과정이다.
건축물의 구조와 종류는 굉장히 다양하다. (철근 콘크리트, 철골, 목조, …)
어떤 자재를 사용하고, 해당 자재들을 어떻게 조립하는지에 따라 건축물의 특성은 크게 달라진다.
이와 같이 소프트웨어 아키텍처는 시스템의 전체적인 동작을 결정하고, 시스템의 품질 성능(성능, 확장성, 유지보수성, 보안 등)에 직접적으로 영향을 미친다.
소프트웨어 아키텍처를 선택할 때는 다양한 요소(요구사항, 복잡성, 기술 스택, 경험, 비용 및 시간 등)들을 고려하여 적절한 패턴을 선택해야한다.
오늘은 그 중 가장 기본적인 아키텍처인(사실상 표준), 레이어드 아키텍처에 대해서 알아보도록 하자.
레이어드 아키텍처란?
레이어드 아키텍처란 소프트웨어 시스템을 관심사 별로 여러개의 계층로 분리(계층화)한 아키텍처를 뜻한다.
각 계층은 어플리케이션 내에서 특정 역할과 책임이 있다. 그들은 자신의 역할에만 집중한다. 여기서 중요한 것은 구성 요소간 관심사가 분리되었다는 점이다.
이들은 추상화된 인터페이스로만 소통한다. 이 때, 소통은 자신에게 인접한 하위 계층에 요청을 보내는 방식으로 진행된다. (자신보다 상위 계층이나, 인접하지 않은 계층에는 요청하지 못한다.)
여기서 핵심은 단방향 의존성이다. 하위 계층은 상위 계층을 몰라야한다. 하위 계층은 인터페이스만 제공하고 요청만 받을 뿐이다.
가장 일반적인 레이어드 아키텍처는 4-tier 아키텍처(프레젠테이션, 비즈니스, 영속성, 데이터베이스)이다.
4-tier 아키텍처의 계층구조는 아래 사진과 같다.
각 계층의 특징에 대해 알아보자.
Presentation Layer
사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분이다.
이 외에 비즈니스 로직 등은 해당 계층의 관심사가 아니다!
Business Layer
비즈니스 로직을 구현하는 부분이다. 실제로 시스템이 구현해야 하는 핵심 로직을 담당한다.
Presentation Layer로 부터, 사용자의 요청을 전달받고 해당 요청을 실질적으로 처리하는 부분이다.
Persistence Layer
데이터의 영구 저장과 관리를 담당하는 부분이다.
웹 어플리케이션의 데이터베이스와의 상호작용을 처리하며, 데이터베이스와의 상호작용을 추상화한다.
Database Layer
실제 데이터베이스를 뜻한다.
CLOSED
레이어드 아키텍처에서 ‘닫혀있다’(CLOSED)는 중요한 개념이다.
이는, 계층간 요청이 이동할 때 인접한 계층을 통과하는 것을 의미한다.
예를 들어, Presentation Layer에서 Persistence Layer로 요청이 이동하기 위해서는 Business Layer를 거쳐야한다.
그러면 왜 계층을 뛰어넘어 바로 접근하는 것이 좋지 않은 방법일까?
생각해보면 Presentation Layer에서 직접 DB에 접근하는 것이 여러 계층을 거치는 방법보다 훨씬 빠를 것이다. (사실 불필요하게 느껴지기까지 한다.)
하지만 이는 관심사가 분리되지 않은 형태이다.
관심사를 분리하는 이유에 대해 생각해보자.
우리는 왜 이토록 관심사를 분리하고, 다른 계층에게 영향받지 않는 독립적인 계층을 만들기 위해 노력하는걸까?
이는 한 계층에서 변경이 발생했을 때, 다른 계층에 영향을 받지 않게 하기 위해서이다.
콘솔 기반 자동차 경주 게임이 있다고 가정해보자.
요구사항이 변경되어 이제는 콘솔 기반이 아닌 웹어플리케이션 기반으로 변경해야한다.
이 때, 관심사가 적절히 분리되고 계층 구조가 잘 이루어진 어플리케이션이라면 사용자와 직접적으로 연결된 Presentation Layer 에만 변경이 생긴다.
게임의 핵심 로직에는 변경이 없기 때문에 다른 계층들에는 변화가 발생하지 않는다.
(계층 분리가 되어있지 않다면, 전체 코드 중 UI 관련 코드들을 직접 찾아서 고쳐주어야한다.)
OPEN
항상 모든 계층이 닫혀있어야하는 것은 아니다.
특정 요청에만 추가적인 계층이 필요한 경우가 있을 것이다.
예를 들어 DB에 이미지를 넣기 전 이미지 합성을 하는 계층을 추가하고 싶다고 가정하자.
이 계층은 해당 기능을 사용하는 요청에서만 필요하다.
이런 경우 해당 기능을 사용하는 요청에 한해서만 이미지 합성 계층을 사용하고, 그렇지 않은 요청의 경우 해당 계층을 우회하도록 한다.
이와 같이 요청이 특정 계층을 우회하고 그 아래의 계층으로 이동가능하게 하는 것을 '개방한다'(OPEN)고 말한다.
계층 아키텍처에서는 계층 구조와 요청 흐름을 문서화하는 것이 아주 중요하다.
어떤 계층이 열려있고 닫혀 있는지, 그 이유까지 문서화 하거나 적절하게 전달해야한다.
(그렇지 않으면 유지 관리, 테스트, 배포 등에서 많은 어려움을 겪게 된다.)
싱크홀 패턴
이는 요청이 싱크홀처럼 뚝 떨어지는 것을 의미한다.
다시 말해 하위 레이어를 거치긴 하지만, 막상 그 레이어에서는 추가적인 작업 없이 그저 전달만 하는 경우를 뜻한다. (이는 불필요한 오버헤드이다.)
예를 들면, 고객 데이터를 검색하라는 요청이 들어왔을 때 Business Layer에서는 해당 요청을 Persistence Layer에게 전달하고 결과값을 추가적인 작업 없이 다시 Presentation Layer로 넘겨주는 경우가 있다.
public class CustomerService {
private final CustomerRepository customerRepository;
/***/
public Customer find(int customerId) {
return customerRepository.findById(customerId);
}
}
이런 경우, 레이어를 개방하여 상위 레이어에서 직접 요청을 하는 방식으로 수정할 수 있다.
물론 이는 트레이드 오프의 영역이기 때문에, 적절한 방식을 선택하는 것이 좋다.
선택을 할 때 일반적으로 80-20 규칙을 따른다.
이는 요청의 20%는 단순 통과 처리하고, 80%는 비즈니스 로직을 수행한다는 규칙이다.
이 비율이 역전되고 단순 통과 처리되는 요청이 많아지면, 해당 계층을 개방하는 것을 고려할 수 있다.
장단점
글을 마무리하며 레이어드 아키텍처의 장단점에 대해 알아보도록 하자.
🟢 장점
코드의 재사용성 및 유지보수성
각 계층이 관심사별로 분리되어있으므로, 코드의 재사용성과 유지보수성이 향상된다.
변화에 유연하게 대처
각 계층이 독립적으로 개발, 확장, 변경이 가능하다.
또한, 각 계층에서 기능이 확장되거나 변경이 발생할 경우 해당 계층의 코드만 변경이 된다.
즉 변화에 유연하게 대처한다.
테스트 용이성
각 계층이 독립적으로 테스트 가능하므로, 단위 테스트나 통합 테스트가 용이하게 수행된다.
🔴 단점
오버헤드
계층간 통신을 통해 동작하기 때문에, 데이터의 전달 및 변환 과정에서 일부 오버헤드가 발생한다. (through pass)
이는 계층이 많아질수록 더 증가한다.
복잡성
계층간 통신을 위한 인터페이스와 로직을 추가해야하므로 복잡성이 증가한다.
특히, 대규모 프로젝트에서는 계층 간의 관리와 유지보수가 복잡해질 가능성이 크다.
참고 자료
'프로그래밍' 카테고리의 다른 글
OAuth2.0 란? (2) | 2023.07.07 |
---|---|
[소프트웨어 아키텍처] 계층형 아키텍처에서 헥사고날 아키텍처(Hexagonal Architecture)로 (1) | 2023.05.22 |
[Java] 제너릭(Generic) - 무공변성, 공변성, 반공변성 (1) | 2023.04.16 |
[Java] LinkedHashMap (0) | 2023.03.13 |
[Java] 함수형 인터페이스와 람다 (5) | 2023.03.12 |