전부터 DDD, 도메인 주도 설계라는 용어를 익히 들어왔다. 애자일, TDD처럼 이른바 신세대 개발자에게 필수적인 소양으로 다가왔다. 나한테는 아직 와닿지 않았다.
도메인이란 건 소프트웨어를 통해 해결하려는 현실의 문제고, 도메인 로직이란 건 현실의 문제를 해결하기 위해 소프트웨어를 통해 구현된 로직이란 거잖아? 도메인 로직은 Separation of concern 원칙에 의해 JPA, Spring MVC, Kafka와 같은 인프라 기술과 분리해서 관리하면 되지. 객체지향의 다향성과 스프링 등을 활용한 IoC Container, AOP를 통해 Separation of concern을 실현하면 되는 거고. ERD를 설계하고 ERD에 나타난 Entity를 통해서 각 도메인을 분리하면 될 것 같은데. 실제로 개발해 보니까 그럭저럭 프로젝트도 진행되고. 도메인 주도 설계란 걸 지금 당장 알아야 할까?
이와 같은 생각을 하며 DDD에 대한 학습을 미뤄 왔다. 그러다 계기가 생겼다. 예전에 같이 부트캠프에 다니던 동기가 말했다. "우리 도메인 주도 설계 합시다."
이 사람 때문에 도메인 주도 설계 공부를 처음 시작하게 됐다. 도메인 주도 설계란 건 생각보다... 복잡한 모양이다. 우선 빠르게 핵심만 학습하고 세세한 건 이후에 필요에 따라 학습하고자 했다. 이런 상황에서 추천받은 책이 반 버논이라는 사람이 지은 "도메인 주도 설계 핵심 (Domain-Driven Design Distilled)"라는 책이다. 200 페이지가량 되는 얉은 책이므로 빠르게 독파할 수 있을 듯하다. 이 책을 통해 도메인 주도 설계의 핵심가치와 개념을 익히고자 한다.
높은 가치를 주는 소프트웨어 설계 과정에서 사용되는 방법론이라고 볼 수 있다. DDD의 근본은 방법론이라는 것이다. 그럼 어떤 방법론일까?
DDD는 바운디드 컨텍스트 내에서 보편언어를 모델링하는 것에 대한 방법론이다.
이 책에서는 "설계를 하지 않는 것"을 경계하고 있다. 소프트웨어 설계가 선행되지 않는다는 건, 하나의 비즈니스 언어에 대해 개발자의 수만큼의 설계가 혼재한다는 것을 의미한다. 각 개발자가 나름의 방식으로 비즈니스를 이해하고 서로 소통이 제대로 이루어지지 않은 채 개발을 한다면, 프로젝트가 얼마나 산으로 갈까?
비즈니스 모델과 개발자가 개발할 소프트웨어는 동기화를 이루어야 한다. 이 동기화를 완벽하게 해내기란 어려울 것이다. 아무리 비즈니스를 분석하고 설계한다고 하더라도 모든 이해관계자가 완벽하게 똑같은 이데아를 공유하지는 못할 것이다. 그러나 각 이해관계자의 머릿속에 있는 모델들의 간극을 최소화해야 한다.
설계는 미래의 비용을 최소화하는 수단이다. 개발된 시스템은 휘발적인 것이 아니다. 계속 사용되고, 유지보수될 것이다. 얼마나 그 시스템을 사용해야 하고, 나쁜 설계를 수정하는 것이 얼마나 많은 비용을 야기하는지 생각해 보자. 미래에 발생할 수많은 야근을 생각한다면, 지금 당장 설계가 하고 싶어진다.
DDD에서는 두 가지 수준의 설계를 제시한다. 전략적 설계는 거시적 개념이며, 전술적 설계는 미시적 개념이라고 나는 이해했다.
바운디드 컨텍스트 (Bounded Context)라는 전략적 설계 패턴을 사용하여 도메인 모델을 분리한다. 바운디드 컨텍스트에 대해서 자세한 내용은 아직 안 읽었으나, 지금 느낌으로 말하자면 바운디드 컨텍스트는 큰 틀에서 도메인을 여러 개로 분리하는 것이다. 도메인의 분리는 "컨텍스트"를 고려하여 논리적으로 이루어진다.
전략적 설계는 바운디드 컨텍스트 내 보편 언어 (Ubiquitous Language)를 개발하는 과정도 포함한다. 보편 언어는 하나의 팀에 속한 이해관계자들 간에 일관적인 소통을 위한 언어라고 이해할 수 있다.
여러 개의 바운디드 컨텍스트를 매핑하여 통합하는 방법이다. 컨텍스트 맵 (Context Map)은 2개의 바운디드 컨텍스트를 통합하면서 그 사이에 존재하는 팀의 관계, 기술적 메커니즘을 정의한다.
Entity와 Value object를 알맞은 크기의 애그리게잇으로 묶는 데 사용되는 것이 애그리게잇 패턴이다.
도메인 이벤트를 사용함으로써 도메인을 명확하게 모델링하는 데 도움을 받을 수 있다. 또한 도메인에 발생한 이벤트에 대한 정보를 다른 시스템에서 알아야 한다면, 이벤트의 내용을 시스템과 공유하는 것 또한 돕는다.
공유 대상은 로컬의 바운디드 컨텍스트일 수 있고, 다른 원격의 바운디드 컨텍스트일 수도 있다.
앞으로 추가적인 학습을 이어나가도록 하겠다.