Backend/Design Pattern

[Software Design] 헥사고날 아키텍처(Hexagonal Architecture) 톺아보기

Emil :) 2024. 6. 3. 19:42
728x90
반응형

서론


모 회사에서 기술면접을 진행하는 도중, 헥사고날 아키텍처에 대해 알고있냐는 질문을 받았다.
대충 어떤 모양새인지 흐릿하게는 알고 있었는데, 괜히 대답했다가 이도저도 아닌 대답을 내놓을 것 같아서 모른다고 했음(...)

사실 헥사고날 아키텍처나 TDD는 실무에 적용하기 어렵다는 이야기를 많이 들었어서, 그런 내용에 집중하기보다 기본기를 쌓는게 더 중요하다고 생각하는데, 그래도 기본적인 이론과 장단점에 대해서는 파악을 하는 것이 좋을 것 같다.

이론적인 부분은 훨씬 좋은 아티클과 글이 차고 넘치니, 이론에 대해 의미없이 포스팅 하는 것보단 스스로 생각해본 포스팅이라고 이해하시면 편하시겠다.

참고


https://tech.osci.kr/hexagonal-architecture/

 

헥사고날 아키텍처(Hexagonal Architecture) : 유연하고 확장 가능한 소프트웨어 디자인 🌟 feat. Java Exam

오픈소스컨설팅 테크블로그 헥사고날 아키텍처(Hexagonal Architecture) : 유연하고 확장 가능한 소프트웨어 디자인 🌟 feat. Java Example 헥사고날 아키텍처란?Uncategorized -

tech.osci.kr

https://velog.io/@mrcocoball2/MSA-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-3.-%ED%97%A5%EC%82%AC%EA%B3%A0%EB%82%A0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-Hexagonal-Architecture

 

[MSA 알아보기] 3. 헥사고날 아키텍처 (Hexagonal Architecture)

헥사고날 아키텍처(Hexagonal Architecture)는 포트 앤드 어댑터(Port and Adaptor) 아키텍처라고도 불리며 고수준의 비즈니스 로직을 표현하는 내부 영역과 인터페이스 처리를 담당하는 저수준 외부 영역

velog.io

https://zkdlu.tistory.com/4

 

헥사고날 아키텍처(Hexagonal Architecture)

기존의 계층형 아키텍처는 DIP를 적용해도 한계가 있고, 도메인이 인프라에 의존하게 되면서 도메인적인 관심사와 기술적인 관심사가 섞이게 됩니다. MSA에서는 여러 종류의 어플리케이션을 호

zkdlu.tistory.com

 

본론


헥사고날 아키텍처의 정의

출처 : https://reflectoring.io/spring-hexagonal/

한마디로 정리하자면, 입력 포트와 출력 포트를 구분하고 낮은 결합도로 유연한 코드 구성과 테스트의 용이성을 위한 아키텍처이다.

헥사고날 아키텍처는 포트, 어댑터 로 불리우는 인터페이스를 통해 내/외부와 소통하고, 이 때문에 포트&어댑터 아키텍처라고도 불린다.

헥사고날 아키텍처에 대해 이해하려면 조금 생소한 용어들에 대해 이해가 필요한데, 정리해보면 다음과 같다.

포트(Port)

외부 세계와 애플리케이션을 이어주는 구간이다, 인/아웃 바운드로 나뉜다.
흔히들 알고있는 MVC 구조에서 서비스로 이해하면 쉽다.
조금 특이한 것은 기존 MVC 구조에서 Service는 Controller가 return해줄 데이터를 DTO든 Json data든 만들어서 return 해주는 방식으로 진행되는데, 헥사고날 아키텍처에선 인바운드 포트로 API 호출이 들어오고, 아웃바운드 포트로 호출에 대한 로직에 대한 외부 처리가 진행된다는 것이 특징이다.

원래 위처럼 이해를 했었는데, 잘못 알고 있었다.
인바운드는 기존처럼 요청이 들어오면 그에 대한 response를 return하는 방식으로 이루어져 있고,
아웃바운드는 애플리케이션 레이어에서 DB, 외부 API등과 같은 외부와 통신하는 포트이다.

만약 MSA환경에서 서비스를 운영하고, 어떤 도메인에선 RDB를 쓰고, 어떤 도메인에선 NoSQL을 쓰는 환경이라고 가정해보자. 기존 환경대로라면 RDB와 NoSQL에 담긴 데이터를 결합해서 핸들링해야하는 경우가 있으면 구현 로직을 수정해야 하는데, 이렇게 포트 기반으로 움직이면 RDB에 코드를 꼽았다가 뽑고 다시 NoSQL에 코드를 꼽아서 데이터를 가져오는 방식으로 유지보수성을 개선시킬 수 있는 장점이 있다.

그렇다면 왜 이렇게 구분해놓은걸까? 이렇게까지 구분을 할 필요가 있나? 싶어서 조금 생각해봤는데, 결국 SOLID의 일환이라는 것 을 알 수 있었다.

가장 떠오르는 것은 책임의 분리이다. 인바운드 포트의 경우 "외부로부터 입력을 받고 내부로 전달해준다." 에서 책임 끝! 더 이상의 뭔가를 하진 않는다. 반대로 아웃바운드 포트도 "내부 로직의 결과물을 외부로 전달만 해준다." 에서 책임 끝. 이렇게 정말 원자단위로 쪼개면 파일도 많아지고 코드도 많아질텐데, 이렇게까지 해야하나? 라는 생각이 들지만, 시스템의 규모가 커질 수록 이렇게 잘게 쪼개는게 확장에 이롭다는건.. 실제로 현업에서 겪어봤으니 더이상 의문점을 가지진 않겠다. 

즉, 헥사고날 아키텍처도 오로지 포트를 통해서 로직을 처리함으로써, 선언부와 구현부를 철저히 분리했다는 것을 알 수 있다.

어댑터(Adapter)

어댑터는 인프라나 web같은 저수준의 API들이 도메인 로직에 있는 포트를 사용할 수 있게 해준다.
MVC로 치면 Controller의 역할. 네이밍이 조금 생소해서 그렇지 익숙한 MVC에 빗대서 이해해보면 조금 쉽다.

유즈 케이스(Use Case)

비즈니스 로직 또는 규칙을 구현한다. MVC의 Service에 해당한다고 보면된다.
어? 근데 포트도 Service라고 하지 않음? 맞다. 흐름을 따져보면 이런 느낌이다.

즉, use-case의 구현체가 서비스가 되고, 서비스에서 어떤 로직을 수행할 지 인바운드 포트를 통해 의사결정을 한다고 이해하면 쉽다.

내부/외부에 대한 추가적인 고민

헥사고날 아키텍처는 지속적으로 포트를 통해 내부/외부와 통신하는 방법을 선택하고 있다.

그렇다면 여기서 말하는 내부/외부는 정확히 뭘 의미하는 걸까? 이 부분에 대해서 다소 이해가 가지 않아 다른 포스트를 작성해주신 분에게 질문을 남겨봤고, 답변을 얻을 수 있었다. 먼저 외부의 개념에 대해 이해해보자.

아하. 외부라고 함은 곧 애플리케이션 코드 외의 인프라 레이어만을 의미하는 줄 알았는데, 그게 아니라 처리 중인 도메인 외 다른 환경을 의미하는 것이었다.

즉, 아웃바운드 포트라고 해서 DB랑만 통신하고, 이런게 정해져있는게 아니라, 어떤 방법이던지 도메인 외부와 통신하는 것을 아웃바운드 포트라고 한다.
아웃바운드 포트와 외부에 대한 이해가 되었으니, 인바운드 포트와 내부는.. 사실 컨트롤러를 통해 호출되고 서비스에서 호출되는 비즈니스 로직이 전부라서, 크게 이해되지 않는 부분은 없었다.

헥사고날 아키텍처의 장단점

여러 소프트웨어 디자인의 목적은 결국 책임을 간소화하고, 확장성을 높이는 데에 그 의의를 두고 있다.
헥사고날 아키텍처도 여타 아키텍처와 크게 다르지 않은 장단점을 가지고 있는데, 내가 느낀 장단점은 다음과 같다.

장점 1) SRP와 OCP, DIP를 매우 충족한다.

  • SRP는 인바운드,아웃바운드, 어댑터 등의 역할을 통해 확인할 수 있었다.
  • OCP는 이와 같은 맥락으로, 예를 들어 내부에서 상품명을 가져올 때, 어떻게 가져오는지는 선언부가 알 필요가 없다. 아웃바운드 포트가 이에 대한 구현을 담당하고 있으므로, 이는 곧 확장에 대한 유연함을 증명하기도 한다.
  • DIP는 외부 인터페이스들이 내부 로직에 의존하고 있다. 때문에 비즈니스 로직이 외부의 변화(컨트롤러, 서비스 등)에 영향을 받지 않는다.

장점 2) 비즈니스 로직에 집중하여 개발이 가능

  • 구현하고자 하는 목표만 개발하면된다. 외부에서 어떻게 호출하는지는 개발과 업무 프로세스만 알고 있으면 됨.
  • 나중에 방식이 바뀌더라도, (DB를 통해 불러오던 데이터를 외부 API를 통해 불러온다던가) 부품을 갈아끼우는 것처럼 해당 포트만 바꿔주면 된다. 선언부는 알 필요가 없음.

단점 1) 코드의 복잡도가 올라간다.

  • 초기에 이러한 설계를 하려면 전반적인 업무 프로세스와 인프라 구조를 모두 알고있어야함. 따라서 설계 난이도가 어렵다.
  • 코드의 양이 많아지고 구조가 복잡해진다. 그러나! 경험상 익숙해지면.. 문제될 게 없더라.

단점 2) 추상화 레벨이 올라감, 불필요한 오버헤드의 발생 가능성이 있다.

  • 새로운 모델들(포트, 어댑터)이 추가된 만큼 레이어들 간에 전달해줘야 하는 맵핑객체(DTO 같은거)가 추가된다. 이에 따른 비용이 발생하기 마련.

결론


이렇게 헥사고날 아키텍처에 대해 이론을 파악해보고, 이해하는 시간을 가져봤다.

여러 예제 코드를 보면서 이해했는데, 단어가 생소해서 이해하는데 시간이 꽤 오래걸렸다.
면접을 봤던 회사에 질문할 때, "코드를 작성하면서 어떤 것을 가장 중요시하느냐?" 라는 질문을 했는데, "헥사고날 아키텍처를 사용하고 있는데, 레이어 간 의존관계를 명확히 하는것을 굉장히 중요하게 여기고있다." 라는 답변을 받았다.

직접 공부해보니, 그 답변이 나온 배경에 대해서도 알 수 있게 되어 흥미로운 학습이었다.

구독 및 하트는 정보 포스팅 제작에 큰 힘이됩니다♡

728x90
반응형