티스토리 뷰
의존 역전에 대한 고찰
객체지향의 가장 큰 장점은 의존 방향을 우리가 원하는 대로 제어하기 쉽다는 점이다. 예를 들어 A → B 구조에서 B의 변동 가능성이 클 경우, A → I ← B 형태로 구조를 바꿔서 A를 변화와 확장으로부터 보호하는 것, 그게 핵심이다. 여기서 중요한 건 A와 I가 같은 바운더리 안에 있어야 한다는 점이다. 왜냐하면 I는 A가 원하는 인터페이스이기 때문이다. 그런데 의존을 역전시켰다고 하면서 I와 B를 같은 바운더리에 위치시키는 경우가 종종 보이는데 이는 의존 역전에 대한 오해다.
의존 역전의 본질은 인터페이스를 사용했다는 것 자체가 아니라, 변동에 대한 제어 주도권을 역전시켜 가져왔다는 점이다.
마이크로서비스에서의 의존역전
MSA의 기술적 성장은 안정화되어 가고 있지만, 개발자들의 인식은 그에 미치지 못하는 경우가 많다. 대부분의 마이크로서비스는 원래 하나의 모놀리식 애플리케이션이었고, 결국 하나의 비즈니스 문제를 해결하기 위한 것이라는 사실을 잊어서는 안된다.
여기서 중요한 개념이 도메인이다. 도메인은 우리가 해결하고자 하는 비즈니스 문제이지, 특정 서버나 애플리케이션이 아니다. 그런데도 종종 개발자들은 도메인을 하나의 서버로 대입시키고 기술적 경계에만 집중한다. 이러다보면 실무에서 다른 마이크로서비스와의 협업이 어색해질수 있다. 도메인은 여러 마이크로서비스의 묶음으로 봐야 자연스럽다. 왜냐하면 우리가 해결해야 하는 비즈니스 문제는 특정 서비스 하나에 국한되지 않기 때문이다.
MSA를 다루는 개발자들이 도메인을 하나의 거시적인 비즈니스로 인식하지 못하고, 자신이 관리하는 서비스에서 다른 서비스와의 결합도를 낮추는 데에만 집중한다는 것이다. 그런데 인터페이스 하나 달랑 만든다고 해서 결합도가 낮아졌다고 생각하는 건 굉장한 착각이다. 실무 경험이 있다면 조금만 생각해보자 의존하는 다른 서버의 의존성을 떨어트린다고 해서 진짜 내가 관리하는 서버의 도메인 객체들은 보호받는가? 아닐 확률이 높다. 결국 하나의 거시적 도메인이라면 강결합을 받아드리는것이 자연스럽다.
진짜 의존 역전이라면, 내가 호출하는 외부 서비스의 변화와 확장에도 불구하고, 제어 주도권이 나의 서비스에 있어야 한다. 그런데 현실적으로 이는 거의 불가능하다. 왜냐하면 기획의 시선에서는 마이크로서비스 하나하나에 관심이 없고, 전체 비즈니스에 관심이 있기 때문이다. 그리고 그게 당연한 현실이다.
결국 의존 역전이 의미 있는 순간은 다음과 같다:
- 인프라스트럭처 혹은 온전한 외부 서비스(예: PG, 지도 API)
- 관리하는 서버가 의존하는 기능에 대해 온전히 제어권을 갖고 의존 역전이 가능할때
- 명백한 변화 가능성과 확장이 예측될 때
마이크로서비스에서 헥사고널 아키텍처가 어색한 이유
이제 본론이다. 왜 마이크로서비스 환경에서는 헥사고널 아키텍처가 어색할까?
하나의 서버가 하나의 도메인이 될 수 없기 때문이다. MSA는 의도적으로 서버를 쪼갠 것이고, 그 과정에서 도메인이 함께 쪼개졌다고 착각하는 경우가 많다. 하지만 도메인은 여전히 하나의 비즈니스 문제이고, 여러 서비스에 걸쳐 흩어져 있다. 하나의 서비스에 헥사고널 아키텍처를 적용하면 강제로 도메인을 분리한 듯한 어색함이 발생한다.
코드상으로는 보호된 것처럼 보여도, 실제론 그렇지 않다. 왜냐하면 기획자가 정의한 도메인은 하나의 서버나 하나의 코드베이스로 표현될 수 있는 개념이 아니기 때문이다.
헥사고널 아키텍처를 적용해서 나만의 완벽한 세상을 구축했다고 착각할 수도 있다. 어떤 확장이 와도 우아하게 대처할 수 있을 것처럼 느껴진다. 하지만 현실은 기획자의 피드백 한 마디에 그 세계는 쉽게 무너진다. 결국 그들이 상상한 ‘비즈니스 문제’가 개발지의 아키텍처 경계를 넘나들게 만들기 때문이다.
그리고 헥사고널 아키텍처는 비용이 많이 든다. 패키지 수만 봐도 일반적인 레이어드 아키텍처보다 4배 이상 많아진다. (https://youtu.be/g6Tg6_qpIVc?si=4O7tJRWnXaii1uQX&t=1823) 작은 팀, 빠른 개발, 빈번한 피드백 루프가 필요한 MSA 환경에서는 상당히 부담스러운 구조다. 외부 시스템에 대한 의존 영향을 줄이고 싶다면 꼭 헥사고널 아키텍처일 필요는 없다. Adapter나 ACL(anti-corruption layer)만으로도 충분히 해결 가능한 경우가 많다. 스프링 같은 DI 프레임워크를 사용해서 비즈니스 컴포넌트를 관리한다면 테스트 작성에도 어려움이 없다.
헥사고널 아키텍처는 훌륭한 개념이다. 하지만 모든 곳에 적용할 수 있는 만능 도구는 아니다. 특히 마이크로서비스 환경에서는, 아키텍처보다는 비즈니스 문제의 흐름과 현실적인 제어권 분포를 더 먼저 고민해야 한다. 진짜 의존 역전은 인터페이스 몇 개로 해결되지 않는다. 현실에 맞는 구조를 고민해야 한다.
'Development' 카테고리의 다른 글
Next.js + Vercel 환경에서 한글 검색 구현 삽질기록 (0) | 2025.05.04 |
---|---|
병렬 처리 모델은 모두 IO 작업에 최적화되어 있다 (CPU 바운드 작업을 조심하자) (0) | 2025.04.16 |
WebRTC란 무엇인가? (0) | 2024.10.06 |
Null 공포증을 내려놓자 (1) | 2024.07.24 |
절차지향 프로그래밍 붐은 온다.. (객체지향에 얽매이지 말자) (0) | 2024.05.15 |