처음 컬리에 입사했을 때 팀 내에서는 Java/Spring 스택으로 백엔드 개발을 진행하고 있었습니다. 이전 회사에서도 같은 스택을 사용해서 적응하기에 별 무리 없겠구나~ 했는데 웬걸, 프로젝트 구조가 그동안 봐왔던 것과는 상이했던 거였죠.
원래는 계층형 아키텍처를 사용하였습니다. 흔히 백엔드 개발을 시작하면 배우게 되는 그 Controller/Service/Repository 구조입니다. 가장 단순하고 이해하기 쉬운 구조여서 그런지 학생들을 가르칠 때도 많이 사용하죠. 저도 예외는 아니었습니다.
그러나 마주친 것은 이름조차도 낯선 헥사고날 아키텍처(Hexagonal Architecture)였습니다. 어댑터, 유스케이스, 포트 등 현란한 용어들 사이에서 저는 정신을 차릴 수가 없었습니다. 헥사고날 아키텍처를 처음 도입했던 팀원들은 회사를 떠났고, 남겨진 저희들은 학습된 내용이 없는 상태에서 더듬더듬 기존 구조를 참고하며 코드를 작성하였습니다. 벌써 1년이 넘었네요. 문득 팀원 한 분이 그런 말씀을 하신 겁니다.
우리는 지금 헥사고날 아키텍처 구조를 잘 따라가고 있을까?
사실 자신 있게 그렇다고 답할 수 없는 상태였습니다. 정확한 개념도 모르고, 왜 도입했는지 이유도 모른 채 어쩌다 보니 여기까지 와버렸으니까요. 스터디의 필요성을 느낀 저희는 책 한 권을 고르고 학습을 시작하기로 하였습니다.
책 이름은 "만들면서 배우는 헥사고날 아키텍처 설계와 구현"입니다. 1장, 2장을 읽으면서 책의 워딩이 좀 지나치게 어렵다고 생각이 들더군요. 예제도 라우터 같은 네트워크 도메인을 들어서 그런지 이해가 잘 되지는 않았습니다. 결국 헥사고날 아키텍처의 전체적인 구조만 훑어본 후 다른 참고할만한 레퍼런스를 찾아보았습니다.
역시 유튜브 만한 게 없죠. NHN에서 진행한 콘퍼런스에서 클린 아키텍처에 대한 발표를 진행한 적이 있었습니다. 제목은 클린 아키텍처지만, 그 안에 헥사고날 아키텍처에 관한 내용도 들어있는 것 같아 해당 내용을 정리하게 되었습니다. 서론이 조금 길었네요.
1. 소프트웨어 아키텍처의 중요성
소프트웨어 아키텍처가 도대체 뭘까요? 소프트웨어가 제공하는 가치는 두 가지가 있습니다. 바로 기능/구조인데 이 중에서 소프트웨어 아키텍처는 구조에 해당합니다.
보통은 기능이 더 중요하다고 생각하지 않나요? 저만해도 기능이 더 중요하다는 생각을 가지고 있으니까요. 사실 그렇지 않나요? 개발이라는 게 기능을 만드는 거지 구조를 만드는 것이 아니니까요.
그러나 로버트 마틴(클린 코드 및 클린 아키텍처의 저자)은 저와 다른 생각을 하고 있었나 봅니다. 바로 구조가 더 중요하다고요. 영상에서는 구조가 더 중요한 이유를 어질러진 방을 빗대어 설명하고 있습니다.
방 안에서 물건들은 기능을 뜻하고, 물건들이 어질러져 있는 것은 구조를 의미합니다. 물건을 하나 샀다고 가정하고, 이 방안에 놓는다면 어떻게 하면 될까요? 그 물건은 적당한 자리에 잘 놓일 수 있을까요? 아마 그 물건(기능)도 역시나 저 어지러운 대열에 합류할 것입니다.
이 방이 바로 저희가 생각하는 이상적인 방(코드) 일 것입니다. 근데 이게 과연 가능할까요? 거의 최소한의 물건(기능), 미니멀리즘을 추구하는 사람만이 구성할 수 있을 것 같은데요. 사실 보통 실무에서는 이런 적은 수의 기능을 한 방(프로젝트)에 담지는 않겠죠.
이게 바로 현실적인 클린 코드의 형태일 것입니다. 많이 들어있고 언뜻 보면 복잡해 보일지는 몰라도, 나름의 질서가 있어 구조를 파악하기 어렵지 않은 상태. 물건(기능) 하나를 사서 놓는다 하여도 금방 좋은 자리를 찾을 수 있겠죠.
좋은 아키텍처는 왜 중요한 걸까요? 저희가 하는 코딩의 목적은 요약하면 세 가지입니다. 컴퓨터에게 원하는 일(기능)을
- 더 정확히(버그 수정)
- 더 빠르게(성능 개선)
- 더 많이(기능 추가)
시키는 것이죠. 만약 프로젝트가 좋은 아키텍처로 구성되어 있다면, 필요한 시스템을 만들고 유지보수하는 데 투입되는 인력을 최소화할 수 있습니다. 구조가 좋다면 수정하기가 쉽다는 뜻이고 이것은 즉, 수정하는 데 비용이 적게 든다는 의미입니다.
물론, 이미 기능이 완성되어 앞으로도 변경 사항이 없을 프로그램은 신경 쓸 필요가 없습니다. 아무리 구조가 복잡하다 하더라도 이미 완성되어 있으니 말이죠. 그런데 이런 경우가 많을까요?
2. 좋은 아키텍처를 구성하는 방법
좋은 아키텍처를 구성하는 방법에는 여러 가지 원칙이 있습니다. 아키텍처 패턴이라는 것은 좋은 아키텍처를 잡기 위한 레시피입니다. 따라 하는 것만으로도 좋은 원칙들이 많이 지켜지고, 원칙들을 지키며 코딩하기 쉽도록 도와주게 됩니다.
그러면 아키텍처 패턴을 어떻게 잘 활용할 수 있을까요? 일반적인 레시피를 생각해 보면 됩니다.
1. 일단은 레시피를 따라 해 보기
2. 원칙들을 학습하고 이해한 후에 다시 레시피 대로 따라 해 보기
3. 각각의 프로젝트에 레시피를 적용해 보기
4. 고민이 되는 지점들은 원칙에 맞게, 혹은 크게 벗어나지 않는 선에서 타협하며 적용하기
그러면 어떤 아키텍처를 따라 하면 될지 알아봅시다. 후보는 두 가지가 있습니다.
먼저 첫 번째로, 계층형 아키텍처가 있습니다. 제가 서론에서 말씀드린 바로 그 아키텍처입니다. 웹/도메인/영속성으로 계층을 나누고 아래에 있는 계층이 위에 있는 계층에게 서비스를 제공합니다.
장점 | 단점 |
- 구조 단순 - 처음 시작할 때 적합 - 보편적이라 모두가 익숙함 |
- 업무 도메인에 대해 아무 것도 말해주지 않음 - 소프트웨어가 커지고 복잡해지면 조직화에 도움 안 됨 - 데이터베이스 주도 설계 유도 |
두 번째로, 클린 아키텍처입니다. 이 발표의 주인공이죠. 계층형 아키텍처와 굉장히 비슷하지만, 이 아키텍처는 도메인이 중심이 됩니다. 의존성 역전을 이용하여 도메인을 주인공으로 삼고 있습니다. 화살표 방향이 영속성에서 도메인으로 바뀌었습니다.
장점 | 단점 |
- 규칙 단순 - 도메인이 세부 사항에 의존하지 않는다 - DDD 적용 용이 - 비즈니스 규칙에 집중하기 쉽다 |
- 패키지 구조가 계층형보다 복잡하다 - 익숙하지 않아 처음에 버벅일 수 있다 - 레퍼런스가 적다 |
3. 클린 아키텍처
클린 아키텍처란, 로버트 마틴이 여러 좋은 아키텍처의 장점들만을 모아 하나로 통합을 시도한 아키텍처입니다. 해당 아키텍처들은 헥사고날 아키텍처, BCE(Boundary-Control-Entity), DCI(Data, Context and Interaction) 등이 있습니다.
공통의 목표는 관심사의 분리며, 공통의 핵심 규칙은 의존성의 방향은 안쪽을 향한다입니다.
클린 아키텍처가 좋은 건 알겠는데 어떻게 학습을 하면 좋을까요? 클린 아키텍처에 대한 바이블과 쿡북이 각각 한 권씩 있습니다.
바로 로버트 마틴이 저자인 클린 아키텍처와 톰 홈버그의 만들면서 배우는 클린 아키텍처입니다.
클린 아키텍처는 다들 한 번씩은 들어보셨을 겁니다. 개발자들이 한 번씩은 펼치거나 사본다는.. 그러나 완독한 사람은 극히 소수인 바로 그 책 맞습니다. 저도 방안에 있지만 용기가 없어서 펼쳐보지는 못했네요. 수많은 원칙과 실천법으로 이루어져 있습니다.
만들면서 배우는 클린 아키텍처는 실제로는 헥사고날 아키텍처를 다룬다고 합니다. 개인적으로 한 번은 읽어보고 싶은 책입니다. 책 분량도 비교적 적어 부담 없이 완독할 수 있을 것 같습니다. 쭉 따라가며 기본 개념을 익히기에 좋다고 합니다.
4. 클린 아키텍처는 애매합니다
클린 아키텍처는 핵심 규칙 2가지 외에는 케이스 바이 케이스라 애매한 지점이 많습니다. 애매할 때는 기준이 필요합니다. 영상에서는 기준을 다음과 같이 정의하고 있습니다.
그럼 클린 아키텍처는 모든 상황에서 항상 좋을까요? 그렇지는 않습니다. 소규모 프로젝트를 진행할 때, 개발자 모두가 클린 아키텍처를 이해하고 있지 않을 때, 모두가 사용하기로 합의하지 않았을 때는 쓰지 않기로 합니다.
클린 아키텍처가 기존 아키텍처보다 패키지가 복잡하다고 하였는데, 그럼 얼마나 복잡한 걸까요? 다음 사진에서 알아볼 수 있습니다.
확연히 차이나는 것을 알 수 있는데요. 이렇게 많이 만드는 이유는 패키지화해서 각각의 계층을 세분화하기 위함입니다. 경계를 뚜렷하게 긋기 위해서는 패키지와 클래스가 더 필요한 거죠. 어쨌든 더 좋은 구조를 위한 트레이드오프라고 생각하면 편할 것 같습니다.
참고
'레퍼런스' 카테고리의 다른 글
[Medium] 시스템 디자인 인터뷰의 골든룰 (0) | 2024.03.13 |
---|---|
[Medium] 클린 코드: Null 반환을 피하는 법 (0) | 2024.03.11 |
[Medium] 2024년 자바 개발자 면접 가이드 (2) (0) | 2024.03.04 |
[Medium] 2024년 자바 개발자 면접 가이드 (1) (0) | 2024.02.28 |
[Medium] lombok과 record, 어떤 것이 더 좋은 선택일까? (0) | 2024.02.19 |