도서 소개
에이콘 소프트웨어 아키텍처 시리즈. 이 책은 도메인 주도 설계를 통해 엔터프라이즈 애플리케이션을 구축하는 방법을 풍부한 구현 예제를 통해 구체적으로 설명한다. 스프링, REST, NoSQL 등을 활용해 도메인 모델을 중심으로 올바른 소프트웨어 구조를 만들어가는 과정을 보여주며, CQRS와 이벤트 소싱 등을 활용해 도메인 주도 설계를 구현하는 실용적 방법을 다룬다.
빠른 가치 창출을 위한 올바른 DDD 시작 방법, 헥사고날(hexagonal)이나 SOA, REST, CQRS, 이벤트 중심, 패브릭/그리드 기반 등 다양한 아키텍처에 맞춘 DDD 사용 방법, 엔터티를 올바르게 설계하고 적용하는 방법과 값 객체를 대신 사용해야 하는 시점, DDD의 새롭고 강력한 기법인 도메인 이벤트에 관한 완전한 이해, ORM이나 NoSQL을 비롯한 다양한 데이터베이스에 맞춰 리파지토리(repository)를 설계하는 방법 등을 다루고 있다.
출판사 리뷰
★ 요약 ★
이 책은 도메인 주도 설계를 통해 엔터프라이즈 애플리케이션을 구축하는 방법을 풍부한 구현 예제를 통해 구체적으로 설명한다. 스프링, REST, NoSQL 등을 활용해 도메인 모델을 중심으로 올바른 소프트웨어 구조를 만들어가는 과정을 보여주며, CQRS와 이벤트 소싱 등을 활용해 도메인 주도 설계를 구현하는 실용적 방법을 다룬다. 그동안 도메인 주도 설계를 프로젝트에 적용하는 과정에서 어려움을 겪었던 개발자에게 이 책은 완벽한 교과서가 될 것이다.
★ 이 책에서 다루는 내용 ★
■ 빠른 가치 창출을 위한 올바른 DDD 시작 방법
■ 헥사고날(hexagonal)이나 SOA, REST, CQRS, 이벤트 중심, 패브릭/그리드 기반 등 다양한 아키텍처에 맞춘 DDD 사용 방법
■ 엔터티를 올바르게 설계하고 적용하는 방법과 값 객체를 대신 사용해야 하는 시점
■ DDD의 새롭고 강력한 기법인 도메인 이벤트에 관한 완전한 이해
■ ORM이나 NoSQL을 비롯한 다양한 데이터베이스에 맞춰 리파지토리(repository)를 설계하는 방법
★ 이 책의 구성 ★
1장: DDD를 시작하며
1장에선 DDD를 사용할 때 얻을 수 있는 이익과 DDD를 달성하는 방법을 소개한다. 여러분의 프로젝트를 수행하고 여러분의 팀이 복잡도로 고민하고 있을 때 DDD가 수행할 수 있는 역할은 무엇인지 배우게 된다. 여러분의 프로젝트가 DDD에 투자해도 좋을지 평가할 방법을 찾게 된다. 여러분이 흔히 고려할 수 있는 DDD의 대안이 무엇이고, 왜 그런 대안이 흔히 문제를 일으키곤 하는지 고민하게 된다. 1장에선 여러분의 프로젝트가 첫 발을 내딛기 위한 DDD의 기반을 다루며, 이는 여러분의 관리자와 도메인 전문가와 기술 팀 구성원을 설득하는 데 도움이 될지도 모른다. 이는 여러분이 성공에 이르는 방법에 관한 지식으로 무장해 DDD를 사용할 때 겪게 될 도전을 마주할 수 있도록 해줄 것이다.
실제 현실에서 겪게 되는 DDD의 도전을 마주하고 있는 가상의 회사와 팀에 관한 케이스 스터디도 함께 다룬다. 혁신적인 멀티테넌트(multitenant) 환경의 서비스로서의 소프트웨어(SaaS) 기반 제품을 만들고자 하는 이 회사는 DDD를 적용하며 흔히 겪게 되는 많은 실수를 경험하지만, 팀이 문제를 해결하고 프로젝트를 이어갈 수 있도록 해주는 중요한 발견을 하게 된다. 이 프로젝트에선 스크럼 기반 프로젝트 관리 애플리케이션을 개발하며, 대부분의 개발자가 관련돼 있다. 이 케이스 스터디는 이어지는 장에서도 계속해서 활용된다. 각각의 전략적 패턴과 전술적 패턴을 팀의 시각에서 학습하게 되며, 팀의 실수뿐만 아니라 팀이 성공적인 DDD 구현을 위해 성숙해나가는 과정을 함께 다룬다.
2장: 도메인, 서브도메인, 바운디드 컨텍스트
도메인(Domain)이나 서브도메인(Subdomain)이나 핵심 도메인(Core Domain)은 무슨 의미이고, 이를 사용해야 하는 이유와 사용하는 방법은 무엇일까? 우리의 케이스 스터디에서 프로젝트 팀이 저지르는 실수를 통해 이 질문의 답을 찾아본다. 이 팀은 첫 번째 DDD 프로젝트를 시작하며 자신들이 일하고 있는 서브도메인과 바운디드 컨텍스트와 정확한 유비쿼터스 언어를 이해하는 데 실패한다. 사실, 이들은 전략적 설계에 전혀 익숙하지 않으며, 단순히 전술 수준에서의 이익을 위해 전술적 패턴만을 활용하고 있었다. 이 때문에 초기 도메인 모델 설계에 문제가 발생하게 된다. 다행스럽게도 이들은 희망을 찾을 수 없는 늪에 빠지기에 앞서 무엇이 잘못됐었는지 찾게 된다.
여기에는 바운디드 컨텍스트를 적용해 모델을 올바르게 구분하고 분리하는 데 관한 중요한 메시지가 담겨 있다. 흔히 빠지는 잘못된 패턴의 적용에 관해 다루며, 패턴을 효율적으로 구현하는 방법에 관해 충고한다. 이를 통해 이들의 세 번째 바운디드 컨텍스트와 새로운 핵심 도메인과 책에서 사용되는 주요 예제에서 올바르게 모델링 개념을 분리해내게 된다.
기술적인 측면에서만 DDD를 적용하며 고통을 느꼈던 독자라면 2장의 내용에 크게 공감하게 될 것이다. 여러분이 아직 전략적 설계을 제대로 시작하지 않았다면, 성공적인 여정을 시작하는 올바른 방향을 찾게 된다.
3장: 컨텍스트 맵
컨텍스트 맵(Context Map)은 팀이 비즈니스 도메인과 요로 모델 사이의 경계와 통합이 진행되는 형태를 이해할 수 있도록 도와주는 강력한 도구다. 이를 위한 기법은 단순히 시스템 아키텍처의 다이어그램을 그리는 데 국한되지 않는다. 이는 엔터프라이즈 내부의 여러 바운디드 컨텍스트와 하나의 모델에서 다른 모델로 객체를 매핑하는 데 사용되는 패턴 사이의 관계를 이해하는 문제다. 복잡한 비즈니스를 갖고 있는 엔터프라이즈에서 바운디드 컨텍스트를 제대로 구성하기 위해선 이 도구의 사용이 중요하다. 3장에선 프로젝트 팀이 처음으로 생성했던 바운디드 컨텍스트(2장에서 다루는)의 문제를 이해하기 위해 컨텍스트 매핑을 적용하는 과정을 살펴본다. 그리고 새로운 핵심 도메인을 설계하고 구현해야 하는 팀이 그 결과로 만들어진 깔끔한 두 바운디드 컨텍스트를 활용하는 방법을 보여준다.
4장: 아키텍처
우리 모두는 이미 계층 아키텍처(Layers Architecture)에 관해 알고 있다. 하지만 계층이 정말 DDD 애플리케이션을 다루는 유일한 방법일까? 그렇지 않다면 어떤 다른 아키텍처가 있을까? 여기선 헥사고날((Hexagonal),(포트와 어댑터(Ports and Adaptors)), 서비스 지향, REST, CQRS, 이벤트 중심(파이프와 필터(Pipes and Filters), 장기 실행 프로세스(Long-Running Process)나 사가(Saga), 이벤트 소싱(Event Sourcing)), 데이터 패브릭/그리드(Data Fabric/Grid) 기반 등의 여러 아키텍처 안에서 DDD를 사용하는 방법을 고민한다. 프로젝트 팀은 이런 여러 아키텍처 스타일을 적용하게 된다.
5장: 엔터티
첫 번째로 다룰 DDD 전술 패턴은 엔터티(Entity)다. 프로젝트 팀은 엔터티에 너무 크게 의존해서, 값 객체(Value Object)로 설계해야 하는 중요성을 간과하게 된다. 이로 인해 데이터베이스와 영속성 프레임워크의 과도한 간섭으로 엔터티를 남용하는 문제에 관해 논의하게 된다.
엔터티를 사용하는 올바른 방법에 익숙해진 다음에는 엔터티를 설계하는 방법에 관한 다양한 예제를 다루게 된다. 유비쿼터스 언어를 엔터티로 표현하는 방법은 무엇일까? 어떻게 엔터티를 테스트하고 구현하고 저장할까? 5장에선 이런 문제를 하나씩 다뤄가며 가이드를 제시한다.
6장: 값 객체
프로젝트 팀은 초기에 값 객체를 사용한 중요한 모델링 기회를 놓쳤다. 이 팀은 여러 관련 속성을 불변하는 묶음으로 모으는 데 주의를 기울여야 했을 순간에, 엔터티의 개별적 속성에만 너무 집중했었다. 6장에선 엔터티가 아닌 값을 사용해야 하는 시기를 결정하기 위해 모델의 특성을 식별하는 방법을 논의하면서 값 객체의 설계를 여러 방향에서 살펴본다. 6장에선 통합을 진행할 때 값이 수행하게 되는 역할이나 표준 타임의 모델링과 같은 다른 중요한 주제도 함께 다룬다. 이어서 도메인 중심 테스트를 설계하는 방법, 값 타입을 구현하는 방법, 애그리게잇의 일부로 이들을 저장해야 할 때 영속성 메커니즘으로 인한 나쁜 영향을 피하는 방법 등도 이야기한다.
7장: 서비스
7장에선 하나의 개념을 도메인 모델 안의 잘 짜여진 무상태 서비스(Service)로 모델링해야 하는 시점이 언제인지 보여준다. 여러분은 엔터티나 값 객체가 아닌 서비스를 설계해야 하는 시점과, 비즈니스 도메인 로직을 처리하거나 기술적 통합을 위해 도메인 서비스를 구현하는 방법을 확인하게 된다. 서비스를 사용하는 시점과 서비스를 설계 하는 방법에 관한 사례로서 프로젝트 팀이 내린 결정을 살펴본다.
8장: 도메인 이벤트
에릭 에반스가 그의 책을 출판했던 시점에선 도메인 이벤트(Domain Event)가 DDD의 한 부분으로 소개되기 이전이었다. 모델에서 발행하는 도메인 이벤트가 왜 그렇게 강력한지와, 비즈니스 서비스의 통합과 자동화를 지원하는 가운데 도메인 이벤트를 사용하는 여러 방법을 배우게 된다. 애플리케이션은 기본적으로 여러 종류의 기술적 이벤트를 보내고 처리하지만, 도메인 이벤트만의 특징이 무엇인지 구분해 논의한다. 설계와 구현을 위한 가이드를 제공하며, 선택할 수 있는 옵션과 그에 따른 장단점을 알려준다. 이어서 발행-구독(Publish-Subscribe) 메커니즘을 만드는 방법, 엔터프라이즈를 아우르며 구독자를 통합하는 방법, 이벤트 저장소를 생성하고 관리하는 방법, 흔히 겪게 되는 메시징 문제에 대처하는 방법 등을 논의한다. 또한 프로젝트 팀이 이를 올바르게 적용하는 과정과 각 방법만의 장점을 조명한다.
9장: 모듈
모델 객체를 다른 컨테이너에 속한 객체와의 결합도는 제한하는 가운데 올바른 크기의 컨테이너에 담아내는 방법은 무엇일까? 이런 컨테이너가 유비쿼터스 언어를 반영하도록 하려면 어떻게 이름을 붙여야 할까? 패키지나 네임스페이스를 넘어서, 언어와 프레임워크에서 제공하는 좀 더 최신의 모듈화 기능(OSGi, 직소(Jigsaw)와 같은)은 어떻게 활용할 수 있을까? 여기선 프로젝트 팀이 여러 프로젝트에 걸쳐 모듈을 사용하는 방법을 살펴본다.
10장: 애그리게잇
애그리게잇은 아마도 DDD의 전술 도구 가운데 가장 이해도가 낮은 도구일 것이다. 그렇지만 몇 가지의 경험 법칙(rules of thumb)을 적용하면 애그리게잇을 더 간단하고 빠르게 구현할 수 있다. 여러분은 작은 객체 클러스터의 주변으로 일관성 경계를 구축하면서 복잡도의 벽을 부수고 애그리게잇을 사용하는 방법을 학습하게 된다. 프로젝트 팀은 그다지 중요하지 않은 부분에 너무 큰 관심을 둬서 몇 가지 잘못된 방향을 선택하는 실수를 저지르게 된다. 우린 팀의 이터레이션을 따라가면서 모델링 과정에서 겪게 되는 문제와 팀이 저지른 잘못이나 그 밖의 결정사항을 분석한다. 팀은 노력을 기울이면서 핵심 도메인에 대해 더 깊이 이해할 수 있게 됐다. 우린 팀이 트랜잭션과 결과적 일관성(eventual consistency)을 올바르게 적용해 분산 처리 환경에서 확장성과 성능을 더 높인 모델을 설계하면서 자신들이 저지른 실수를 고쳐가는 과정을 살펴본다.
11장: 팩토리
이미 『GoF의 디자인 패턴』에선 팩토리에 관한 충분한 이야기를 했는데도 왜 이 책에서 다시 이를 언급하려고 할까? 11장에선 팩토리에 관한 세로운 이야기를 하려는 게 아니다. 그보다는 팩토리가 어디에 위치해야 하는지 이해하는 데 집중한다. 물론 DDD의 설정에 맞춰 제 역할을 하는 팩토리를 설계하는 몇 가지 팁도 함께 소개한다. 프로젝트 팀이 클라이언트 인터페이스를 단순화하고 모델의 사용자가 멀티테넌트(multitenant) 환경에서 재앙적인 버그를 유발하지 않도록 막으면서 팩토리를 생성하는 방법을 확인하자.
12장: 리파지토리
리파지토리(Repository)는 단지 단순한 데이터 접근 객체(Data Access Object, DAO)가 아닌가? 왜 우린 데이터베이스가 아닌 컬렉션을 흉내기 위해 리파지토리를 설계하는 방안을 고려해야 할까? 그리드 기반의 코히런스(Coherence) 분산 캐시를 지원하거나 NoSQL 키-값 저장소를 사용하는, ORM을 사용한 리파지토리를 설계하는 방법을 학습하자. 이런 부가적인 영속성 메커니즘은 리파지토리라는 구성 요소에서 오는 강력함과 다재다능함으로 인해 프로젝트 팀을 편안하게 해준다.
13장: 바운디드 컨텍스트의 통합
지금까지 여러분은 컨텍스트 매핑의 상위 수준 기법을 이해했고 전술 패턴을 활용할 수 있게 됐지만, 모델의 통합을 실제로 구현할 때는 어떤 일이 일어날까? DDD에선 어떤 통합 옵션이 주어질까? 13장에선 컨텍스트 매핑을 통해 모델의 통합을 구현하는 몇 가지 방법을 소개한다. 프로젝트 팀이 핵심 도메인과 그를 지원하는 바운디드 컨텍스트를 통합하는 방법에 기반해 통합의 지침을 제공한다.
14장: 애플리케이션
여러분은 핵심 도메인의 유비쿼터스 언어에 따라 모델을 설계했다. 또한 그 사용법과 정확성에 따라 충분한 테스트를 만들었고, 실제로 동작함을 확인했다. 하지만 여러분의 팀에 속한 다른 구성원이 해당 모델을 둘러싼 애플리케이션의 다른 영역을 설계할 때는 어떻게 해야 할까? 그들은 모델과 사용자 인터페이스 사이에서 데이터를 전달하기 위해 DTO를 사용해야 할까? 애플리케이션 서비스(Application Service)와 인프라는 어떻게 동작할까? 14장에선 익숙해졌을 프로젝트에서 선택할 수 있는 옵션을 살펴보며 이 문제를 다룬다.
부록 A: 애그리게잇과 이벤트 소싱: A+ES
이벤트 소싱(Event Sourcing)은 애그리게잇을 저장하기 위한 중요한 기술적 접근법이며, 이벤트 중심 아키텍처(Event-Driven Architecture)를 만드는 기반을 제공한다. 애그리게잇이 생성된 후 발생하는 일련의 이벤트를 통해 애그리게잇의 전체 상태를 표현하기 위해 이벤트 소싱을 사용할 수 있다. 이벤트를 발생 순서를 지켜 다시 재생함으로써 애그리게잇의 상태를 재구축할 수 있다. 따라서 이벤트는 영속성을 단순화하고 복잡한 행위 속성에서 개념을 포착하도록 해주는 가운데, 이벤트 자체가 여러분 자신의 시스템과 외부 시스템에 지대한 영향을 미치는 요소가 된다.
작가 소개
저자 : 반 버논
소프트웨어 디자인과 개발, 아키텍처에서 25년 이상의 경력을 쌓아온 숙련된 소프트웨어 장인이다. 혁신적인 방법을 사용해 소프트웨어의 디자인과 구현을 단순화할 수 있는 리더다. 1980년대부터 객체지향 언어를 사용한 프로그래밍을 시작했고, 1990년대 초기 스몰톡 도메인 모델링부터 도메인 주도 설계의 개념을 적용하기 시작했다. 넓은 비즈니스 도메인에 걸쳐 경험을 쌓았고, 이런 도메인에는 우주항공, 환경, 지리정보, 보험, 의료, 통신 등이 포함된다. 또한 재사용 가능한 프래임워크나 라이브러리를 만들고 개발을 가속시키는 도구를 구현하는 등의 기술적 노력을 계속해왔다. 국제적인 컨설팅이나 강연을 진행해왔고, 여러 대륙에서 도메인 주도 설계의 구현에 관한 수업을 개설했다. www.VaughnVernon.co에서 근황을 확인할 수 있으며, 트위터 아이디는 @VaughnVernon이다.
목차
1장 DDD를 시작하며
나도 DDD 할 수 있을까?
내가 왜 DDD를 해야 하지?
__비즈니스 가치를 제공하는 것은 어려울 수 있다
__DDD가 해줄 수 있는 일
__도메인의 복잡성과 씨름하기
무기력증과 기억 상실
__왜 무기력증이 일어나는가
__무기력증이 당신의 모델에 한 일을 보라.
DDD는 어떻게 하는가?
__유비쿼터스지만 보편적이지는 않다.
DDD를 사용하는 데서 오는 비즈니스 가치
__1. 조직이 그 도메인에 유용한 모델을 얻는다.
__2. 정교하고 정확하게 비즈니스를 정의하고 이해한다.
__3. 도메인 전문가가 소프트웨어 설계에 기여한다.
__4. 사용자 경험이 개선된다.
__5. 순수한 모델 주변에 명확한 경계가 생긴다.
__6. 엔터프라이즈 아키텍처의 구성이 좋아진다.
__7. 애자일하고, 반복적이고, 지속적인 모델링이 사용된다.
__8. 전략적인 동시에 전술적인 새로운 도구가 적용된다.
DDD 적용의 난관
__도메인 모델링의 합리화
__DDD는 무겁지 않다
소설과 한 바구니의 현실
마무리
2장 도메인, 서브도메인, 바운디드 컨텍스트
큰 그림
__서브도메인과 바운디드 컨텍스트의 활용
__핵심 도메인에 집중하기
왜 전략적 설계가 엄청나게 필수적인가
현실의 도메인과 서브도메인
바운디드 컨텍스트 이해하기
__모델 그 이상을 위해
__바운디드 컨텍스트의 크기
__기술적 컴포넌트로 정렬하기
샘플 컨텍스트
__협업 컨텍스트
__식별자와 액세스 컨텍스트
__애자일 프로젝트 관리 컨텍스트
마무리
3장 컨텍스트 맵
컨텍스트 맵이 필수적인 이유
__컨텍스트 맵 그리기
__프로젝트와