핵사고날 아키텍처의 이해
헥사고날 아키텍처의 주된 목적은 비즈니스 코드를 기술 코드로부터 분리하는 것이다. 그러면 애플리케이션에 대해 자동화된 회귀 테스트를 만들수 있고, 다양한 데이터베이스를 손쉽게 적용할 수 있다.
비즈니스 코드가 어디에 존재해야 하는지, 기술 문제로부터 격리되고 보호돼야 하는 위치를 결정해야 한다. 이것은 우리의 첫번째 핵사곤, 즉 도메인 헥사곤을 생성하게 될 것이다.
- 도메인 핵사곤 : 소프트웨어가 해결하기를 원하는 핵심 문제를 설명하는 요소들을 결합한다. 도메인 핵사곤에서 활용되는 주된 요소는 엔티티와 값 객체다. 엔티티는 식별자를 할당할 수 있는 것을 의미하며, 값 객체는 엔티티들을 합성하기 위해 사용하는 불변 컴포넌트다.
도메인 핵사곤은 실 세계 문제를 이해하고 모델링하는 활동을 나타낸다. 도메인 핵사곤 안에는 중요한 비즈니스 데이터와 규칙에 관련된 엔티티들이 있다. 이것들은 실제 문제에 대한 모델을 나타내기 때문에 중요하다. 엔티티와 값객체로 비즈니스 규칙을 캡슐화 한다.
- 애플리케이션 핵사곤 : 도메인 핵사곤에서 나오는 비즈니스 규칙을 사용, 처리하고 조정하는 방법이 필요하다. 비즈니스 측면과 기술적 측면 사이에 있으며, 양쪽과 상호작용하는 중재자 역할을 한다. 애플리케이션 핵사곤은 포트와 유스케이스를 활용해 이러한 기능을 수행한다.
애플리케이션 핵사곤은 애플리케이션의 특화작업을 추상적으로 처리하는 것이다. 아직 기술 관심사를 직접 다루지 않기 때문에 추상적인 것을 이야기한다. 이 핵사곤은 도메인 비즈니스 규칙에 기반한 소프트웨어 사용자의 의도와 기능을 표현한다. 이러한 작업은 유스케이스로 그룹화되어 제공된다.
※ 유스케이스 : 도메인 제약사항을 지원하기 위해 시스템의 동작을 소프트웨어 영역내에 존재하는 애플리케이션 특화 오퍼레이션을 통해 나타낸다. 유스케이스는 엔티티 및 다른 유스케이스와 직접 상호작용 하고 그것들을 유연한 컴포넌트로 만들 수 있다. 소스코드에서는 인터페이스로 정의된 추상화로 나타낸다.
public interface RouterViewUseCase {
List<Router> getRouters(Predicate<Router> filter);
}
※ 입력포트 : 유스케이스가 소프트웨어 하는일을 설명하는 인터페이스라면 여전히 유스케이스 인터페이스를 구현해야한다. 이것이 입력포트 이다. 다음은 유스케이스 서술된 소프트웨어의 의도를 만족시키는 입력포트를 구현한 것이다.
public class RouterViewInputPort implements RouterViewUseCase {
private RouterViewOutputPort routerListOutputPort;
public RouterViewInputPort(RouterViewOutputPort routerViewOutputPort){
this.routerListOutputPort = routerViewOutputPort;
}
@Override
public List<Router> getRouters(Predicate<Router> filter) {
var routers = routerListOutputPort.fetchRouters();
return Router.retrieveRouter(routers, filter);
}
}
- 프레임워크 핵사곤 : 외부 인터페이스를 제공한다. 애플리케이션 기능의 노출방법을 결정할 수 있는 것이다. 예를들어 프레임워크 핵사곤에서 REST나 RPC 엔드포인트를 정의한다. 외부 소스에서 무언가를 소비하기 위해 데이터베이스, 메시지 브로커, 다른 시스템에서 데이터를 가져오는 메커니즘을 정의하기 위해 프레임워크 핵사곤을 사용한다.
소프트웨어와 통신은 두가지 형태로 발생할 수 있다. 하나는 드라이빙 방식이고 하나는 드리븐 방식이다. 드라이버 관점에서는 입력 어댑터이며, 드리븐 관점에서는 출력 어댑처 이다.
드라이빙 오퍼레이션과 입력 어댑터
드라이빙 오퍼레이션은 소프트웨어에 동작을 요청하는 것이다. 애플리케이션 프로그래밍 인터페이스(API) 가 이에 해당한다. 즉 입력 어댑터는 애플리케이션에서 지원하는 프로토콜을 정의할 수 있다.
드리븐 오퍼레이션과 출력 어댑터
드라이빙 오퍼레이션의 반대편에는 드리븐 오퍼레이션이 있다 이 오퍼레이션은 어플리케이션에서 트리거 되고, 외부에서 소프트웨어 요구사항을 충족시키는 데 필요한 데이터를 가져온다. 일반적으로 드리븐 오퍼레이션은 일부 드라이빙 오퍼레이션에 응답해 발생한다. 상상할 수 있듯 출력 어댑터를 통해서 드리븐 오퍼레이터를 정의한다. 이 어댑터는 그것들을 구현하는 출력 포트와 일치해야 한다.
핵사고날 아키텍처를 도입할때의 장점
회사나 개인 프로젝트에서 소프트웨어를 개발하는 방법을 표준화하는데 도움이 되는 패턴을 찾고있다면 핵사고날 어키텍처는 클래스 패키지 코드 구조가 전체적으로 구성되는 방법에 영향을 주어 이러한 표준을 만드는 기초로 사용할 수 있다. 여러 공급업체와 대규모 프로젝트를 진행해보고 같은 기반 코드에 기여할 수 있는 새로운 개발자를 데려와 써본 수많은 경험에 비추어 보면 핵사고날 아키텍처는 조직이 소프트웨어를 구성하는 기본 원칙을 수립하는데 도움이 된다. 프로젝트를 전환할때마다 개발자는 이전 프로젝트에서 획득한 핵사고날 원칙에 대해 이미 알고 있기 때문에 소프트웨어가 어떤 구조로 되어 있는지 이해하기 위한 완만한 학습곡선을 갖게 된다. 이러한 요소는 특히 기술 부채가 적은 소프트웨어가 가져다 주는 장기적인 이점과도 관련이 있다.
'Programming > 기타' 카테고리의 다른 글
핵사고날 아키텍처의 설계와 구현 - 어댑터의 이해 (0) | 2023.10.25 |
---|---|
핵사고날 아키텍처의 설계와 구현 - 유스케이스 작성 방법 (0) | 2023.10.25 |
Google의 검색 자동완성에 대해.. (0) | 2023.10.14 |
SQL Injection 에 대한 대응 (0) | 2023.10.13 |
Refresh Token에 대한 고찰 (0) | 2023.09.25 |