개발자의 연금, 아키텍처

현실과 미래의 타협

· 13 min read
아키텍처 설계 백엔드

개발자의 연금, 아키텍처

돌아가기만 하면 된다, 살아가기만 하면 된다

저는 대학교 시절 처음 개발이라는 것을 접했어요

시작은 안드로이드 개발이었어요

모든게 새롭고 재미있었죠

내가 입력한 코드에 따라 내가 원하는 결과가 나온다니
제가 설계하는 대로 동작했죠

그때 저는 딱 하나만 신경썼어요

‘돌아가면 된다’

메인 액티비티 하나에 수백 줄 화면 로직, DB 접근, 계산 모두 모여있었어요

아키텍처? 그런 단어는 제 사전에 존재하지 않았죠

지금 생각해보면 그건 연금을 전혀 넣지 않은 채 살아가는 것과 같았어요

지금 당장은 괜찮거든요

문제는 지금 닥쳐오지 않아요

첫 연금 가입, 계층형 아키텍처

먼저 이야기하고 싶은게 있어요

개발이 무엇일까?

다양한 의견들이 나올 수 있지만 저는 이렇게 생각하고 있어요

우리가 겪는 문제를 핵심 비즈니스로 해결하는 것

결국 개발의 핵심, 무기는 비즈니스 로직이라고 생각해요

···

웹 SI 개발을 하는 회사에 취직하고 처음으로 계층형 아키텍처를 만났어요

흔히 말하는 계층형 아키텍처

계층형 아키텍처

역할에 따라 계층을 나누고, 데이터의 흐름은 단방향으로 흘러갔어요

Spring 프로젝트로 설명을 하자면

Presentation -> Controller = UI와 통신을 담당
Application -> Service = 우리의 핵심, 비즈니스 로직
Data -> Repository = DB와의 연결을 담당

이런 형식의 구조가 되는거죠

이렇게 구조적으로 나뉘어있으니 엄청나게 편했어요

  1. 각자 맡은 역할에 따라 팀원별 분업이 자연스럽게 되었어요
  2. 그 당시의 저 같은 신입 사원이 입사하더라도 구조 파악이 빠르게 되었고 소스를 찾아가기 편했어요

만약 처음 개발을 했던 저처럼 회사 코드가 Controller에 다 몰려있었다면?

분업도 힘들뿐더러 신입 개발자는 코드 분석하기에도 힘들었을거에요

계층형 아키텍처를 도입하지 않았더라면 개발을 훨씬 빨랐겠죠
파일 생성하고 어떻게 나눌지 정하고.. 그 과정이 사라지니까요

그런데 그게 꼭 연금이랑 닮았어요

연금을 안내면 지금 당장은 돈이 더 많은 것 같잖아요
하지만 나중에 그 몇 배를 고통으로 돌려받아요

지금의 불편함이 나의 미래를 지켜주는 거죠

그런데 저는 그 연금이 새고 있다는걸 한참 뒤에나 깨달았어요

우리의 비즈니스가 위험했다

처음에는 계층형 아키텍처가 완전 무결하다고 생각했어요

그런데 어느 순간 보였어요

우리의 비즈니스가 오염되고 있었다는 사실을

저는 그때 당시 페이징 처리를 Pageable 객체를 사용해서 하고 있었어요

그리고 Entity 객체도 직접적으로 참조해서 사용하고 있었죠

아래처럼 말이에요

// Service가 JPA를 직접 알고 있는 상황(JPA@Entity, Pageable)
public Page<PostEntity> getPosts(Pageable pageable) {
    return postRepository.findAll(pageable); // JPA가 Service에 침투
}

자연스럽게 Pageable 객체를 Controller -> Service -> Repository로 매개변수를 사용해서 넘겨주고 있었고

JPA Entity 객체를 Repository -> Service -> Controller로 반환하고 있었죠

지금 다시 생각해보면 문제가 있었어요

만약 페이징 처리 방식을 바꾸었더라면?
데이터베이스 종류가 바뀌었다면? NoSQL DB를 사용해야했다면?

비즈니스 오염

Data 계층의 변경이 Service, Controller까지 전파되어 수정해줘야해요

계층형이 나쁜 게 아니에요
방향만 정해줬을 뿐, 무엇에 의존하는지는 막아주지 않았어요
계층을 나눠도 JPA 타입이 Service까지 흘러들어오면 결국 Data가 Business를 오염시키는 거죠

이를 도메인(핵심 비즈니스)오염이라고 부르기도 해요

연금은 가입했지만 수수료가 너무 높아 실질적으로 쌓이는 게 적었던 거에요

더 좋은 연금을 찾아서: 헥사고날 아키텍처

계층형 아키텍처에서 우리의 핵심 Application이 Data에 오염되는 것을 직접 눈으로 확인했어요

그렇다면 이 문제를 어떻게 해결해야할까요?

우리는 이미 Application이 Data에 너무 의존적이여서 발생한 문제라고 인지를 했어요

그러면 그 의존을 약하게 만들면 어떨까요?

여기서 중요한 원칙 하나가 나와요

DIP, 의존 역전 원칙이라고 부르는 그것이죠

헥사고날 아키텍처에서 제일 중요한 개념이에요

구현체를 직접 아는 게 아니라, 그 상위 개념(약속)만 알면 된다

우리는 이전에 Application에서 직접적으로 JPA Entity, Pageable 객체를 알고있었어요

그래서 DB가 바뀌거나 페이징 처리 방식이 바뀌면 Application에서 직접적으로 영향을 받았죠

만약 우리의 Application에서 ‘게시글 목록을 요청하면 게시글 리스트를 돌려준다’라는 약속만 알고 있다면 어떻게 될까요?

JPA를 쓰든 Mybatis를 쓰든 MongoDB를 쓰든 Application에선 몰라도 돼요

만약 예전의 소스를 바꾼다면 아래처럼 바뀔 것 같잖아요

// Service는 약속(PostPort)만 알아요
public PageResponse<PostDomain> getPosts(PageRequest request) {
    return postPort.findAll(request);
}

그 약속을 지키는건 DB 구현체가 할 일이고 우리는 약속에 따라 우리의 비즈니스 로직을 구현하면 되니까요

헥사고날 아키텍처 구조

여기서 외부와의 통신을 위한 약속은 Port라고 하고
그 약속을 지킨 구현체는 Adapter라고 불러요

그래서 헥사고날 아키텍처는 Port & Adapter 아키텍처라고 불리기도 해요

외부에서는 우리의 핵심 Application과 통신을 위해서 약속 규정을 철저히 지키는 Adapter 구현체를 만들어요

모든 외부 통신은 Port의 규정을 지켜야 가능해요

UI에서 우리 Application을 호출할 때도 마찬가지예요

정해진 약속대로 요청이 들어오고, Application은 그 약속대로 응답하면 돼요
이렇게 모든 통신이 Port라는 약속을 통해서만 이루어지기 때문에 Application은 외부가 어떻게 바뀌든 영향을 받지 않아요

연금으로 치면 원금이 외부 시장 변화에 흔들리지 않도록 보호장치를 만든 거예요
우리의 핵심 비즈니스가 바로 그 원금이에요

좋은 연금도 때를 가려야 한다

그렇다고 헥사고날 아키텍처를 무조건 적용하는 것도 좋은 방법은 아니에요

헥사고날 아키텍처를 구성하기 위해선 우리의 비즈니스 로직에 대한 모든 외부 흐름을 약속으로 정의해야해요

그리고 각각의 약속에 대한 구현체들이 필요하죠

기본적으로 시간이 많이 들어가고 시스템이 복잡해질 수 있어요

제가 SI에서 근무할 때는 계층형 아키텍처로 빠르게 개발을 했음에도 시간이 부족했었거든요

만약 헥사고날 아키텍처를 고집했다면 프로젝트 마무리를 쉽게 짓지 못했을거에요

지금 당장에 쓸 돈도 없는데 연금을 유지하는 것도 부담이니까요

결국 중요한 건 내 상황을 아는 것이에요

빠르게 납품해야 하는 프로젝트인지, 오랫동안 유지보수해야 하는 서비스인지
팀의 규모는 어떤지, 비즈니스가 얼마나 자주 바뀌는지
아키텍처는 그 답에 따라 골라야 해요

연금 상품도 내 소득과 나이에 맞는 걸 골라야 하듯이요

우리의 숙제

좋은 아키텍처가 미래를 지켜주는 건 맞아요

하지만 현재를 버텨내지 못하면 미래 자체가 없어요

미래를 위한 선택이 현재를 망가뜨리면, 그건 좋은 선택이 아니에요

현재 우리가 처한 상황에 맞는 아키텍처를 고르고 설계하는 것이 중요해요

아키텍처는 목적이 아니라 도구예요

돌아보면 저는 아키텍처를 공부하면서 단순히 기술을 배운 게 아니었어요

‘돌아가면 된다’고 생각했던 대학생이
계층을 나누는 것만으로 감탄했던 신입이
그 구조 속에서도 비즈니스가 오염되고 있다는 걸 눈치채기까지
꽤 오랜 시간이 걸렸어요

아직도 저는 완벽한 아키텍처를 몰라요

앞으로도 계속 고민하겠죠

하지만 지금 내가 짜는 코드가 미래의 나를 얼마나 편하게, 혹은 힘들게 할지를 한 번쯤 생각하게 된 것

그게 가장 큰 변화인 것 같아요

결국 아키텍처도, 연금도 현실과 미래의 타협이에요

지금의 나의 비즈니스를 잃지 않으면서, 미래의 나 또는 다른 사람을 위해 우리의 비즈니스를 지켜주는 것

그게 제가 생각하는 좋은 설계에요