주니어 개발자는 도메인 주도 설계의 꿈을 꾸는가?

2023-12-31
  • Life
  • Thoughts
  • Postmortem
  • DDD

도메인 주도 설계는 주니어 개발자의 꿈을 꾸는가?

주의!! 이 포스트는 도메인 주도 설계가 무엇인지 하나도 설명하지 않습니다. 이 글은 필자의 경험과 의견에 대한 글이니 정보를 원하시는 분은 다른 글을 봐주세요.

도메인 주도 설계(Domain-Driven Design), 줄여서 DDD라고 부르는 이 개념은 최근 들어 많이 관심 가지게 되었습니다. 도메인 주도 설계라는 용어와 개념 자체는 많이 들었던 부분이지만, 그 본질이 무엇인지 제대로 알지는 못했습니다. 최근 일주일 간 DDD에 관한 상대적으로 쉬운 책을 하나 읽고 DDD의 근-본 책인 도메인 주도 설계(에릭 에반스)을 읽고 있습니다.

아.. 어째서 이 책을 지금에서야 읽게 되었을까요? 아직 2부까지만 읽었으나 머리를 탁 치게 만드는 깨달음과 지나간 세월에 대한 생각이 스쳐 지나갑니다. 이 감각을 기록해놓고자 잠시 책을 덮고 컴퓨터 앞에 앉았습니다.

먼저 저는 처음 웹 개발을 시작했던 때를 떠올렸습니다.

아키텍처가 뭐죠? 먹는 건가요?

처음 웹 서버 개발을 공부하였을 때, Node.js와 Express로 간단한 서버를 개발했습니다. API 엔드포인트 3~4개에, DB는 MariaDB, 테이블은 2~3개, ORM? 3-layer 아키텍처? 그딴거 없고 그냥 Express 미들웨어에 모든 로직을 넣는 프로그래밍이었습니다. 아마 웹 서버 개발을 맨땅에 헤딩하는 식으로 Node.js/Express로 시작해본 사람이라면 아래와 같은 코드는 익숙할수도 있습니다. ㅎㅎ

// 처음 시작할 땐 TS따위 모르므로 JS가 국룰
app.get('/items', (req, res) => {
  connection.query('SELECT * FROM items', (error, results) => {
    if (error) {
      console.error('Error executing MySQL query: ', error);
      res.status(500).json({ error: 'Internal Server Error' });
    } else {
      res.json(results);
    }
  });
});

아아.. 이 얼마나 아름다운 코드입니까? 정말 CRUD 그 자체만 수행하는 데다가 복잡할 것 하나 없는 매우 단순한 코드이죠.

조금 더 커진 프로그램

그렇게 대충 Express와 대충 MariaDB(Mysql), 대충 서버에서 해야 할 이것저것(인증, 유효성 검사, API 문서화, Config 관리, 등등..)을 공부한 저는 다음 스텝을 디뎠습니다. 조금 더 커진 문제 영역을 다루고 더 복잡한 프로그램을 개발해보기 위해 이미 진행되고 있던 프로젝트 팀에 합류했죠.

그 프로젝트는 이미 백엔드 서버가 Node.js/Express/MongoDB 기반으로 짜여져 있었으며, API 엔드포인트도 10개가 넘어가고 DB 테이블도 좀 있는 프로젝트였죠. 하지만 거기에서도 코드는 Express 미들웨어 함수에 비즈니스 로직 + 데이터 액세스 로직을 다 넣고, 이를 Express 라우터에 넣어서 등록하는 형태였습니다.

그 시기의 문제는 여러 가지였습니다.

  1. 비즈니스가 운영되고 있지 않아 비즈니스 로직을 변경할 사항이 많지 않았음
  2. 서버는 개발되기만 하고 API 문서화나 테스트 코드, 전체적인 팀워크 문화가 없음
  3. 초보라서 뭐가 문제인지 잘 모름

결국 그 프로젝트에서 얻은 건 크게 없었죠. 제가 문제라고 인식한 부분은 1, 2번이었고, 나머지 문제들은 기술적으로는 초보였던지라 뭐가 문제인지 잘 몰랐습니다. 1번은 프로젝트 리더가 운영하고 말고를 결정할 사항이라 의견만 열심히 냈었고, 2번은 나름 열심히 개선해보고자 했습니다.

하지만 API 문서화하고 테스트 코드 쓰고 디버깅하는 것도 좋지만, 개발은 하지 못하는 상황이었습니다. 게다가 이 구조와 설계가 맞는 건지조차 분간이 안갔죠.

아키텍처 고민 한 스푼

그렇게 개발도 제대로 하지 못하는 프로젝트를 뒤로 하고, 새로운 팀 프로젝트를 시작하게 되었습니다. 이번엔 3-layer 아키텍쳐를 좀 공부해보고 ORM도 도입해봅니다. 이 프로젝트는 제가 주도적으로 개발에 참여하지는 못했지만, 그래도 간간히 커밋도 하고 아키텍처 회의도 참여하였습니다.

하지만, 이 프로젝트도 이전 프로젝트들과 마찬가지로, 복잡한 문제를 해결하는 소프트웨어는 아니었습니다. 데이터 접근 계층을 추상화하는 ORM 도입, 컨트롤러 - 서비스 - 레포지토리로 이어지는 3계층 아키텍처를 도입하고 나니 그 외엔 딱히 할 게 없었죠. 왜냐면, 복잡한 도메인 요구사항이 없는 CRUD - Only 어플리케이션이었으니까요. 돌이켜보면 3-layer의 역할과 책임 분리도 명확하지 않았던 것 같습니다.

이쯤 되니, 자아 성찰을 좀 하게 됩니다. 뭐가 문제일까요? 뭔가 제대로 소프트웨어를 개발한다는 느낌이 들지 않습니다… 요구사항이 좀 더 복잡해지면? 문제 영역이 좀 더 커지면? 그 때도 지금처럼 개발해도 되는걸까?

그때 도움을 얻고자 펼쳤던 책이 엔터프라이즈 애플리케이션 아키텍처 패턴입니다. 근데 이해가 잘 안되기도 하고, 흥미가 크게 생기지 않아서 몇 부분만 체리피킹으로 읽었습니다. 도움이 된 부분이 있긴 했으나 코드에 어떻게 적용시켜야 할지 감이 잘 안왔죠.

프레임워크의 동앗줄과 기술적인 경험

이때 주위의 소개로 NestJS를 맛봤더니, 오오오오오오 이거야 말로 제가 가려웠던 부분을 시원하게 긁어줬습니다. 어떤 코드와 설계가 무슨 상황에서 좋고 나쁨을 판단하기 힘든 시기에, NestJS라는 프레임워크는 철학을 세우고 이에 따라 프로그래밍 하게끔 저를 인도했습니다. 저는 그저 몸을 맡기고 따라가기만 하면 되었죠.

이때부터 3-layer 아키텍처의 역할과 책임 분리에 힘쓰는 생활을 시작했습니다. 비즈니스 로직은 고민없이 서비스 계층에 밀어넣고, 각 계층이 가지는 역할을 준수하도록 코딩하려고 노력했죠. 개발을 하는 데에 있어서 설계적인 고민이 조금 덜어지고 나니, 개발이 좀 더 수월하고 기능을 구현하는 데에 집중할 수 있었습니다.

기능 만들기와 기술 적용하기

그 이후로 진행한 프로젝트는 주로 두 가지 관심사가 있었습니다.

  1. 프로젝트 요구사항에 따른 기능 구현
  2. 기능을 구현하는데에 적절한 기술 선택과 적용

위를 다른 말로 표현해볼까요?

  1. 프로젝트 요구사항에 따른 기능 구현(기능적 요구사항)
  2. 기능을 구현하는데에 적절한 기술 선택과 적용(비기능적 요구사항)

기능적 요구사항비기능적 요구사항에서 점점 더 관심이 갔던 것은 비기능적 요구사항이었습니다.

왜냐하면, 지금까지 진행하는 개인 / 팀 프로젝트는 문제 영역이 그렇게 크지 않고, 복잡한 비즈니스 로직이 거의 없었습니다. 그러다 보니 서비스 레이어에 간단하게 작성하는 코드 몇줄로 기능적 요구사항을 대부분 표현할 수 있었고, 자연스레 조금 더 역량을 쌓을 수 있다고 생각되는 부분인 기술에 더 노력을 쏟게 되었습니다.

하지만, 생각해보면 진행했던 프로젝트의 도메인에 대한 이해도를 높이려는 노력이 부족했던 것이 아닌지, 도메인 요구사항을 찾으려는 노력이 부족했던 것이 아닌지 생각이 듭니다.

이게 맞나??

결국 저는 프로젝트 도메인에 대한 이해를 제쳐두고, 기술적인 토픽을 주로 찾게 되었습니다. 요즘 기술 토픽이 얼마나 많습니까?

캐싱, 로깅, 모니터링, 관측 가능성, 부하 테스트, 분산 처리 시스템, 대용량 데이터/트래픽 처리 기타 등등등.. 오픈 소스 소프트웨어를 나열하자면 엄청 긴 리스트가 나올 겁니다.

게다가 기업들의 채용 공고는 대부분 기술적인 키워드가 많습니다. 채용 공고에 기업의 도메인 지식에 대한 요구사항을 적기엔 너무 많은 것을 요구하는 것일 수도 있으니, 채용 공고에 기술적인 키워드가 많을 수 밖에 없긴 합니다. 그리고 많은 기업이 채용 공고에 도메인 주도 설계 경험도 적어놓습니다.

하지만 아무래도 언급되는 양 자체가 많은 기술 키워드에 눈이 갈 수 밖에 없었습니다. [도메인 주도 설계]를 읽기 전에는 도메인 주도 설계에 대한 중요성에 대해 잘 모르기도 했구요.

기술 키워드를 좇던 저는 큰 불편함을 느끼지는 못했지만, 지금 하고 있는 게 맞는지 의문은 들었습니다.

도메인에 대한 관심과 이해

이제껏 가져온 기술에 대한 편향적인 관심은 이제 에릭 에반스의 펜침을 맞고 사망했습니다. 이제는 기술과 도메인에 대해 적어도 동등한, 혹은 도메인에 쪼오금만 더 큰 관심을 가져야 겠다는 생각이 들었습니다.

SW 엔지니어는 도메인이라는 문제 영역에 대해 SW로 해법을 만드는 사람이니까요.

DDD는 주니어 개발자에게 중요할까?

주니어 개발자는 Domain-Driven Design Developer를 꿈꿔야 할까요? 적어도 저는 처음 단순한 프로그래밍에서 벗어나 복잡성이 있는 소프트웨어 개발에 발을 디뎠을 때로 돌아간다면, 저를 DDD 설계를 해야 나갈 수 있는 방에 노트북과 DDD 책만 던져주고 감금시켰을 것 같습니다.

세상에 기술에 대한 이야기는 넘쳐납니다. 하루가 지나고 한달이 지나면 새로운 기술이 나오고, 기술 트렌드가 싹싹 바뀌니까요.

하지만, 해야 하는 것은 도메인 요구사항을 구현하는 것입니다. 그리고 도메인 요구사항은 계속 바뀔수도 있고, 도메인 요구사항 자체가 매우 복잡할 수도 있습니다.

도메인 요구사항을 충족시키면서도 유연하게 변경될 수 있는 소프트웨어를 만드는 길에는 DDD가 배트카를 해줄 거라고 믿습니다. DDD와 함께 행복한 개발 생활 보내세요!

Profile picture

Istiopaxx

What is Real? How do you define Real? I`ve been lived in the dream world..