2014년 4월 29일 화요일

도메인 주도 설계와 애자일 개발

왜 모델링이 필요한가?

우리들이 프로그램을 제작하는 과정은 현실의 어떠한 사물이나 동작을 대상으로 하여 이를 추상적 형태로 변환시키고, 변환된 추상적 개념들을 이용하여 컴퓨터 안에서의 여러가지 형태로 실체화 시키는 일련의 과정을 거치게 된다.



프로그래밍에 있어서 어려운 점 가운데 하나는 구현하고자 하는 대상의 본질적인 원리를 정확하게 파악하기가 쉽지가 않다는 점이다. 우리가 오감을 통해 관찰 할 수 있는 범위는 구현 대상의 외형boundary에 한정되기 때문에 이러한 외형에 대한 관찰과 기존 지식을 통해 대상의 본질을 추론해 내야만 한다. 이러한 추론을 통한 추상화 작업을 프로그래밍에 있어서는 모델링이라 부르며 대상의 본질에 통찰해 내는 과정이 제한된 감각과 지식의 틀 안에서 이루어진다는 점 때문에 종종 플라톤 철학의 이데아론에 빗대어 지기도 한다.

인식과 실체의 사이에는 늘 일정한 갭이 존재하기 마련이다.
  
결국, 구현 대상에 대한 이해도를 바탕으로 본질을 정확히 파악해 내고 이를 추상화 해 내느냐가 프로그램의 완성도를 결정하게 된다고 할 수 있다.

모델링에 대해서 좀 더 알아보고 싶다면 아래의 기사를 읽어볼 것을 권한다.(영문)

모든 프로그램은 모델을 지닌다

설계문서를 일체 만들지 않는 프로그래밍이라 해도 모델링 작업은 반드시 거치게 되어 있다. 최소한 우리 머리속 에서라도 말이다. 하지만 두명 이상이 이러한 대상에 대한 인식을 공유하고자 할 때에 모델은 언어를 통해 세상에 그 모습을 드러 낼 수 밖에 없게 된다. UML과 같은 패턴언어는 경험을 패턴화 함으로서 지식 전달에 필요한 시간과 노력을 단축시키는데 사용된다.
혼자서 진행하는 프로젝트라 하더라도 모델링은 부족한 인간의 기억력을 보완해 주고 추상적 개념들을 시각화 해 나타내 줌으로서 프로그래밍에 적지않은 도움을 준다.

객체 지향 프로그래밍과 절차적 프로그래밍

객체 지향 프로그래밍Object-Oriented Programming, OOP이 무엇인지는 많은 문서들에서 설명되고 있으므로 굳이 여기서 언급하지는 않겠다. 다만 필자가 여기서 분명히 해 두고자 하는것은 OOP의 대비되는 개념으로 흔히 구조적 프로그래밍structured programming이 언급되는 경향이 있는데, 이는 잘못된 인식이라는 것 이다. 

프로그램을 객체의 조합으로 보느냐 명령어의 조합으로 보느냐에 대한 기준으로 패러다임을 나누고자 한다면 OOP의 대칭점에 있는것은 절차적 프로그래밍procedural programming이며, 프로그램의 복잡성을 관리하기 위해 계층적인 구조를 가지는 구조적 프로그래밍의 사상은 OOP에도 그대로 살아 있다고 볼 수 있을것이다.

절차적 프로그래밍은 오랜 기간동안 프로그래밍 패러다임의 주류를 이루었으며 지금까지도 처음 프로그래밍을 배울때에도 절차적인 프로그래밍을 통해서 프로그램을 구현하는 방법을 배우게 된다. 이때문에 OOP가 주류가 되었다고 하는 지금까지도 형태는 OOP의 흉내를 내고 있지만 프로그램의 실제 구조는 절차적 프로그래밍을 띄고 있는 경우가 대부분 이다.

절차적 프로그래밍은 배우기 쉽고 빠르게 작성할 수 있으며 성능에 있어서도 효율적인 경우가 많아 아래 소개할 PoEAA에서도 트렌젝션 스크립트 패턴이란 이름으로 취급하고 있다.

PoEAA의 등장과 도메인 주도 설계



2002년 마틴 파울러Pattern of Enterprise Application Architecture(이하 PoEAA)를 통해 엔터프라이즈 어플리케이션에 있어서 OOP가 가져야 할 모습에 대한 재 발견을 이끌어 낸다. PoEAA는 디자인 패턴Design Pattern을 단순히 확장한 개념이라기 보다는 OOP본래의 패러다임에 충실하게 엔터프라이즈 어플리케이션의 각 요소들의 본질과 관계를 새롭게 패턴화 하여 정의하고 있는데, 이 책에서 확립된 개념들은 이후 등장하는 많은 아키텍처들에 큰 영향을 주게 된다. 

에릭 에반스는 2003년 PoEAA를 기반으로 하여 패턴간의 상호 연관성을 실제적인 예제를 곁들여 해설한 도메인 주도 설계Domain-Driven Design(이하DDD) 를 발표한다. 이 책은 출간 직후부터 열렬한 환영을 받는데, 일정수준 이상의 복잡도를 지니는 어플리케이션 개발에 있어서 복잡성을 관리 할 수 있는 실천적인 전략과 패턴들을 제공하고 있었기 때문이다. 


DDD의 네비게이션 맵
DDD에서에서 한가지 아쉬운점은, 의도적인지는 몰라도 PoEAA에서 기술한 여러 개념들에 대한 설명을 생략하고 있어 사실상 PoEAA를 먼저 읽지 않고는 제대로 이해하기가 힘들다는 점 이다. 비단 기업용 어플리케이션이 아니더라도 효율적인 소프트웨어 개발을 위해 모델링에 관심이 있는 개발자라면 이 두권의 책을 꼭 읽어둘 것을 강력히 권한다.(DDD의 경우 국내에도 이대엽씨의 훌륭한 번역으로 번역서가 출간되어 있지만 PoEAA는 절판이되어 구할수가 없다. )

DDD와 애자일 개발의 궁합

다시한번 말하지만 DDD는 지금까지 없던 새로운 개발 패러다임이 아닌 OOP 본래 모습을 되찾자는것이다. 하지만 OOP의 관점에서 객체를 모델링하는것은 말처럼 쉬운 일이 아니다. 동일한 객체라 할 지라도 시각에 따라 다양한 모습의 모델이 존재 가능하며, 복합적으로 상호작용을 하며 움직이는 객체를 설명하기 위해 다양한 모델이 동시에 존재하기도 한다.

인간의 표정에 대한  CG구현은 보이지 않는 뼈와 근육의 움직임에 대해서 모델링이 가능해진 시점에서야 자연스러움을 인정받게 되었다. 이러한 사물(객체)의 본질에 대한 고찰이야 말로 DDD를 수행해야 하는 가장 큰 이유이자 DDD의 수행이 어려운 이유이기도 하다.

DDD 수행에 있어서 애자일 개발 프로세스가 필요한 이유는 두가지이다.
첫번째는 바운더리를 통해 도메인 모델을 추론해 내는 작업을 한번에 해 내는것이 어렵기 때문으로, 모델이 올바른가를 증명하기 위해서는 이를 구현한 코드를 작동시켜보는 방법이 가장 유효한데, 동작을 통해 다시 모델을 개선시키고 구현을 통해 확인해 나가는 방법이 바로 스크럼과 같은 짧은 주기의 반복형 개발 프로세스. 즉, 애자일 프로세스이다. 반면, 한번 정해진 모델에 대해 변경이 쉽지 않은 폭포수형 개발 방식으로는 DDD를 수행하는것이 사실상 불가능하다.

DDD로 수행하는 Scrum 플로우(출전:MSDN)

모델의 완성도를 높여 나가기 위한 위한 정제 프로세스
(출전:domainlanguage.com)


두번째는 모델링에서 구현에 이르는 일련의 작업들이 도메인 영역에 대한 이해도에 직접적으로 연관되어 이루어지므로 폭포수 개발에 따른 전통적인 역할분담(업무분석가or도메인 전문가, 설계자, 코더)으로는 엄청나게 늘어나는 커뮤니케이션 비용을 감당 할 수 없지만, 애자일 개발이라면 도메인 전문가에서 개발자에 이르는 커뮤니케이션 라인이 매우 심플하므로 이것이 DDD에 있어서 애자일 개발 프로세스가 필요한 두번째 이유이다.

위에 소개한 Model Exploration Whirlpool(모델 개발 소용돌이)은 DDD에 기반한 대부분의 개발에서 채택하는 프로세스인데, 눈에 보이는 부분인 시나리오에서 시작해 모델과 코드를 만들어 나가는 작업을 반복해서 수행함으로서 차츰 완성도를 높여 나가게 된다. 이러한 작업들은 기간을 나누어 구분해서 작업하는것이 아니라 동시 다발적으로 늘 이루어져야 하며 특히 시나리오와 모델의 정제작업은 사실상 분리가 불가능하므로 같은 사람이 수행 할 수 있어야 하며 DDD의 저자인 에릭 에반스는 모델 설계자가 코딩 작업에 참여하는것을 완전히 배재해서는 안된다고 말하고 있다.