Eternity's Chit-Chat

aeternum.egloos.com



Domain-Driven Design의 적용-4.ORM과 투명한 영속성 1부 Domain-Driven Design

코드와 모델을 밀접하게 연관시키는 것은 코드에 의미를 부여하고 모델을 적절하게 한다.
-Eric Evans
  

뒤돌아보기

우리는 주문 시스템이 필요해요.”

 

모든 것은 이 한마디로부터 시작됐다. 고객은 주문 시스템을 원한다. 이 시스템이 무엇을 해야 하는지는 아직 잘 모르지만 주문이라는 개념이 도메인의 핵심을 이루는 것 같다. 팀을 구성하고 계획을 세우면서 지속적으로 고객과의 대화를 통해 시스템의 전체적인 윤곽을 그려나갔다. 처음에는 고객이 사용하는 용어가 낯설고 이해하기 힘들었지만 도메인에 대한 이해가 깊어 질수록 고객들과의 의사소통도 크게 문제가 되지 않았다. 고객들 역시 처음에는 UML, REPOSITORY, XP, JUnit과 같은 용어를 사용하는 개발자들을 무슨 화성에서 온 외계인인 양 쳐다 보았지만 지금은 교육과 의사소통을 통해 개발자들의 용어와 적용 기술을 대략적으로나마 이해하게 되었다.

 

고객들과의 지속적인 협력을 통해 도메인을 구성하는 중요 개념들을 식별하고 이를 화이트보드 상에 간단한 UML로 스케치하여 짧은 검토회의를 거쳤다. 고객들은 적은 시간의 교육만으로도 UML의 클래스 다이어그램과 오브젝트 다이어그램을 이해할 수 있었다. 개발자들은 UML을 구현 명세가 아닌 설계 스케치 용도로 사용함으로써 회의 참가자들이 시스템에 반영될 도메인 개념과 개념들 간의 관계에 집중할 수 있도록 유도했다. 클래스 다이어그램의 클래스와 속성, 책임에 사용되는 용어들은 고객들이 업무에서 실제로 쓰고 있는 용어를 사용했다. 이 용어들은 고객과 개발자들이 공통으로 사용하기로 한 것들이다. 물론 적절한 용어가 존재하지 않을 경우 고객들과의 협의를 통해 새로운 용어를 만들기도 했다. 그 용어가 무엇이든 현재는 고객과 개발자들이 주문 도메인을 동일한 언어와 동일한 의미로 바라볼 수 있도록 했다는 점에 그 의의를 두어야 겠다.

 

짧은 검토 회의를 마친 후에 화이트보드에 그려진 UML 다이어그램들을 디지털 카메라로 찍은 후 자리로 돌아와 짝 프로그래머와 함께 식별된 도메인 개념들과 이들의 관계를 코드로 옮기기 시작했다. 물론 실패하는 테스트부터 작성하고 테스트를 통과하도록 코드를 작성하는 규칙에 따라 시스템을 구현해 나갔다. 도메인에는 고객, 주문, 주문 항목, 상품, 금액이라는 개념이 필요하다. 우리는  이 개념들을 고객이 사용하는 용어 그대로 Customer, Order, OrderLineItem, Product, Money라고 명명하기로 했다. 이 클래스들은 고객들이 보더라도 무엇을 의미하는지 한 눈에 알 수 있을 것이다. 각 클래스의 속성과 메소드를 할당할 때에도 원칙은 동일하다. 고객의 용어를 사용한다. 그런 용어가 존재하지 않는다면 고객과의 토의를 통해 선정된 적절한 용어를 사용한다.

 

잘 운영되던 시스템이 다운되자 그동안 묻어 두었던 문제점이 노출되었다. 시스템이 깨끗하게 초기화된 것이다. 고객 정보도 주문 정보도, 그 어느 것 하나 남아있지 않고 공중으로 증발해 버리고 말았다. 그 동안 아무 일도 없었다는 듯 멍하니 돌아가고 있는 시스템을 보자니 울화통이 치민다. 도메인 정보의 영속성을 보장하기 위해 관계형 데이터베이스를 도입하기로 결정하고 데이터베이스 접근 코드에 의한 파급 효과를 제한하고 테스트를 용이하기 위해 전체 시스템의 결합도를 낮춰야 한다는 주장이 제기됐다. 우리는 의존성 주입을 지원하는 Spring 프레임워크를 도입하기로 결정했으며 데이터베이스 로직을 캡슐화할 수 있도록 하기 위해 REPOSITORY를 리팩토링하여 인터페이스와 구현 클래스로 분리했다.

 

비록 몇 가지 기술적인 이슈로 인해 시스템에 몇 가지 변경이 있었지만 도메인 모델 자체의 변화는 거의 없었다. 고객의 개념과 용어를 사용하여 도메인을 모델링하고 모델링된 도메인을 별다는 수정 없이 분석, 설계, 구현 전과정에 걸쳐 사용했다. Spring이라는 새로운 프레임워크를 도입했지만 도메인 모델 자체를 하위 인프라 스트럭처로부터 고립시켰기 때문에 이로 인한 도메인 모델의 변경은 미미한 수준이었다.

 

우리의 도메인 모델은 고객의 용어로 말하고 고객의 의도대로 행동한다. 도메인 모델은 도메인에 관해서 이야기하지만 도메인과 무관한 기술적인 부분에 관해서는 이야기하지 않는다. 분석, 설계, 구현에 이르기까지 도메인 모델의 기본적인 형태는 변하지 않고 유지된다. 이는 도메인에 관한 정신적 모델과 소프트웨어 모델 간의 차이를 의미하는 표현적 차이(representation gap) “또는 의미적 차이(semantic gap)”라는 논점과 관련이 있다. 소프트웨어 모델, 즉 코드가 도메인 모델을 떠오르게 하고 도메인 모델을 바탕으로 예측가능한 방식으로 작동할 경우 두 모델 간의 표현적 차이가 적다라고 한다.

 

Domain-Driven Design은 도메인 모델과 소프트웨어 모델, 즉 코드 간의 표현적 차이를 최소화하기 위한 접근 방법이다. Domain-Driven DesignEJB와 같은 구현 기술이 소프트웨어 개발을 주도함으로써 발생돼는 여러 가지 문제점을 해결하기 위해 기술 주도적인 방식이 아닌 도메인 주도적인 방식으로 소프트웨어를 개발할 것을 주장한다.

 

Domain-Driven Design을 성공적으로 적용하기 위해서는 기본적인 두 가지 요소가 갖추어져야 한다. 하나는 UBIQUITOUS LANGUAGE로 고객과 개발자들 사이에 공통된 용어를 사용하도록 함으로써 의사소통의 단절 및 오해로 인해 잘못된 소프트웨어가 개발되는 것을 방지할 수 있도록 한다. 앞의 예에서 고객과 개발자들이 용어를 협의하고 소프트웨어에 고객의 용어를 반영하도록 노력하는 과정이 바로 UBIQUITOUS LANGUAGE를 구축해 가는 과정이라고 할 수 있다. 또 다른 하나는 MODEL-DRIVEN DEISGN이다. 이 개념은 분석, 설계, 구현의 모든 단계를 관통하는 하나의 모델을 만들자는 개념이다. , 표현적 차이를 줄임으로써 소프트웨어가 도메인의 모습을 투영하도록 만들자는 것이다. 앞의 예에서 하위의 인프라 스트럭처를 변경할 경우에도 기본적인 도메인 모델은 변경되지 않았음에 주목하자. 일반적으로 MODEL-DRIVEN DESIGN을 적용하기 위해서는 표현적 차이가 적은 객체-지향 언어를 사용하고 EJB와 같은 침투적인 인프라 스트럭처 대신 비침투적인 POJO(Plain Old Java Object) 기반의 경량 프레임워크를 적용하는 것이 적합하다.

 

우리는 가능한 한 주문 시스템에 고객의 용어를 반영하고 표현적 차이를 줄일 수 있도록 노력했다. 그리고 인프라 스트럭처의 변경이 핵심적인 도메인 모델에 영향을 미치지 않도록 여러 가지 원칙들을 적용해 왔다. 그렇다면 관계형 데이터베이스를 도입했을 경우에도 별다른 변경없이 도메인 모델의 핵심 구조를 유지할 수 있을까? 답은 그렇다이다. 그러나 관계형 데이터베이스를 도입하기 위해서는 주문 시스템이라는 요리에 몇 가지 재료를 더 얹어야 한다. ENTITY로부터 시작하자.


핑백

  • Domain-Driven Design | Jongmin Kim's Blog 2014-09-02 01:18:19 #

    ... 2009/02/23 Domain-Driven Design의 적용-4.ORM과 투명한 영속성 2부 2009/02/15 Domain-Driven Design의 적용-4.ORM과 투명한 영속성 1부 2009/01/18 Domain-Driven Design의 적용-3.Dependency Injection과 ... more