[DDD ①] 도메인 주도 개발

일반입력 :2008/09/10 10:46

안영회(㈜ITwise 컨설팅 컨설턴트)

에릭 에반스의 DDD(Domain-Driven Design)에서 가장 기억하고 싶은 내용은 ‘하나의 팀에서 하나의 언어로’라는 부분이다. 필자는 경험을 통해 개발(Development)을 끌고 가는 중심에는 해당 업무 즉, 도메인 프로그램 개발의 대상이 되는 업무 영역이 있다는 것을 알게 되었다. 결국, 이 묵직하게 자리하는 것이 시스템 개발의 성패를 좌우하게 된다는 점 배우게 되었다. 이 글에서는 이런 문제에 대한 완벽한 해답을 제시하기 보다는 현실적인 해결책에 대하여 이야기하고자 한다.

‘화성에서 온 남자 금성에서 온 여자’라는 유명한 책이 있다. 이 책에서는 남자와 여자가 본래는 서로 다른 별인 화성과 금성에서 살았기 때문에 애초에 서로 다른 존재이며, 서로 다른 가치관과 생각을 가지고 있었다고 이야기한다. 그런데, 이들이 지구로 옮겨오면서 자신들이 서로 다른 존재였다는 사실을 잊게 되면서 갈등이 생겨나기 시작했다는 내용을 담고 있다.

그런데 이런 갈등은 비단 남녀 사이에만 존재하는 것이 아니다. 프로젝트에서도 마치 ‘화성에서 온 개발자 금성에서 온 고객’이라는 말로 비유할 만한 상황이 벌어진다. XP(Extreme Programming)에서 고객이 개발팀의 일원이 되어야 한다고 하는 말은 매우 공감할만한 이야기다. 밥도 같이 먹고 지속적으로 함께 일하다 보면 화성인과 금성인의 격차가 줄어들지도 모르는 탓이다.

하지만, 경험 많은 개발자(업무 분석가를 포함하여 시스템 개발에 종사하는 소프트웨어 엔지니어를 통칭하는 말)들은 단번에 비현실적이라고 말할 것이다. 업무분석가 역할을 해본 개발자라면 최종 사용자가 될 협업 담당자와 만나는 기회가 충분하지 않다는 사실을 잘 알고 있다.

그래서 복잡한 업무의 경우에는 고객이 아닌 해당 업무분야의 전문가를 포함시키는 경우가 일반적이다. 군 프로젝트에 가면 종종 전역한 장교들을 볼 수가 있고, 금융 프로젝트에서는 해당 업무에 정통한 사람들이 업무 분석가로 활동한다.

어느 정도 고객을 대신할 수 있는 업무 전문가가 있다고 문제가 시원하게 해결되는 것은 아니다. 외주 개발이 보편화된 현실을 감안하면, 서로 다른 행성(도메인)에 살다가 만나게 되는 화성인(개발자)과 금성인(고객)은 근본적으로 차이가 있다.

매일 프로그램의 성능을 고민하고, 새로운 기술 습득으로 일상을 보내던 개발자가 수십 년간 발전해온 산업을 단기간에 이해하는 것은 불가능하다. 반대로 고객의 경우에는 모든 일을 기술적으로 해석하고 사고하는 개발자를 이해하기 어려울 것이다.

이러한 상황을 더욱 악화시키는 것은 서로가 다른 언어를 쓴다는 사실이다. 의사소통을 통해 서로를 이해하기 위해서는 동일한 언어를 사용하는 것은 필수적인 사항인데 말이다.

서로 다른 말을 사용하는 고객과 개발자

개발자가 새로운 분야의 프로젝트를 만나면 도무지 알 수 없는 용어들을 접하게 된다. 특수성이 심한 업무는 고객의 업무 규정이나 보고서를 아무리 읽어도 해독이 불가능한 경우도 있다. 한 페이지의 절반가량을 차지하는 단어가 처음 보는 영문 약어로 기술되어 있는 문서를 상상해보라.

그럼 고객의 입장에서 생각해 보면 어떨까. 바쁜 시간에 불러내서 초보적인 질문에 답변을 해주고 있었다. 그러다가 앞으로 만들어질 프로그램에 궁금한 마음이 생겨, 개발자에게 물어보았더니 도무지 알아들을 수 없는 말만 한다.

이러한 어려움에도 불구하고 고객과 개발자가 잘 소통해야만 원하는 결과를 만들 수 있다. 반대로 이들이 서로 소통에 실패한다면, 원하는 결과는 나오지 않고 서로 잘못된 일만 반목하게 될 것이다. 고객과 개발자가 서로를 맹렬하게 비난하는 현장에 필자 스스로도 참여했던 아픈 경험이 있다.

개발자 사이에서도 각자의 언어가 있다

고객과 개발자 사이에서만 의사소통의 문제가 발생할까? <그림 1>에 표현한 것처럼 도메인을 구성하는 하나의 어휘나 개념이라도 개발자 유형에 따라 상이하게 받아들여진다.

이러한 현상은 서로 다른 유형의 개발자를 한 곳에 모아 동일한 도메인 용어를 가지고 논의를 해보면 쉽게 관찰할 수 있다. 고객을 표현하는 동일한 설계 모델이 없다면 이들 사이의 혼선은 쉽게 예상할 수 있다.

UML 모델과 프로그램의 코드가 완벽하게 일치하지는 않는다. 마찬가지로 DB의 테이블 이름이나 칼럼 이름이 클래스 이름이나 속성 이름과 대응된다 하더라도 동일하지는 않다. 프로그래머와 DB 개발자 커뮤니티 사이에서는 오랜 동안 매우 다른 작명 관행을 유지해오고 있기도 하다.

화면 개발자의 경우도 크게 다르지 않다. 결국은 이들 사이의 구체적인 차이점을 배제한 추상화된 표현법을 공통의 언어로 활용할 수 있다. 일반적으로 설계 모델이 그러한 역할을 해야 한다.

하나의 팀, 하나의 언어

에릭 에반스는 프로젝트 팀이 지향할 목표지점을 분명하게 도식화했다. <그림 2>는 DDD 34쪽의 그림을 간략하게 요약한 것이다. Ubiquitous Language(이하 UL)는 고객과 개발자 양쪽에서 통용되는 어휘를 의미한다. 처음에는 교집합이 없이 나누어져 있다고 하더라도, 프로젝트를 진행하면서 교집합을 충분히 늘려가야 한다.

한편, 어떤 어휘의 경우는 공통의 어휘 구실을 하지 못할 수도 있다. 프로그램에 포함시킬 수 없는 업무의 어휘나 기술 자체에 대한 결정사항은 굳이 서로 논의하여 혼란을 야기할 필요는 없다.

개발자 사이에서는 물론이고, 고객과 개발자가 서로 같은 언어를 쓰기 위한 소프트웨어 커뮤니티의 노력이 없었던 것은 아니다. 다양한 표기법의 모델이 과거부터 존재해왔다. 그리고 이름에서도 드러나듯이 UML(Unified Modeling Language)은 모델링 언어를 표준화하기 위한 목적으로 나타난 것이다.

다만, UML로 작성한 모델이 모두에게 통용되고 있지는 못하다다는 점이 문제다.

필자가 보다 효과적인 모델링 방안을 고민하던 시점에 마침 한 권의 눈에 띄는 책을 만났다. 바로 에릭 에반스(Eric Evans)가 쓴 Domain-Driven Design(이하 DDD)이다. 이 책은 모델링에 대한 풍부한 경험이 없는 개발자에게는 그다지 유용한 책이 되지 않을 수 있다. InfoQ 사이트에서 요약된 이북을 다운로드 받을 수 있다(http://www.infoq.com/minibooks/domain-driven-design-quickly).

방대한 분량의 책 내용을 집약해서 전달하기 위해 곳곳에서 에릭은 DDD의 골격을 이루는 어휘들로 일종의 이동 경로를 그려놓았다. 그 중심에 있는 두 개의 어휘가 있는데 하나는 앞서 언급한 UL이다. 이는 (고객과 개발자) 모두에게 통용되는 언어를 의미한다. 다른 하나는 모델이 주도하는 설계(Model-Driven Design 이하 MDD)이다.

<그림 3>는 개발의 중심에서 서로 다른 노력을 응집시키는 구심점 역할을 하는 모델을 도식화 해본 것이다. 중심에서 발산해나가는 것은 다양한 유형의 개발 결과물 혹은 고객의 시스템에 대한 이해나 기대라고 가정해보자. 고객과 개발자, 유형이 다른 개발자 사이에서라면 모두 조금씩 다른 방향으로 발전하게 마련이다.

이 때 구심점이 되어 이들을 연결해주는 모델이 없다면 각각이 발산해 나가면서 괴리가 커질 것이다.

반면, 모델을 중심으로 강한 응집력이 갖게 된다면 모델은 바로 훌륭한 UL의 역할을 하는 것이다.

고객이 이해할 수 있는 모델

DDD에는 다음과 같은 내용이 나온다.

숙련된 업무 전문가(sophisticated domain experts)가 모델을 이해하지 못한다면, 모델에 문제가 있는 것이다.

만일 모델을 고객이 이해할 수 없다면 어떤 일이 벌어질까? 개발자는 고객과 의사소통을 하기 위해 모델 이외의 다른 무언가를 만들어야 한다. 물론, 이것보다는 모델을 고객과 소통할 수 있게 만들어야 한다.

종종 많은 사람들이 고객이 UML을 직접 활용하는 것은 무리라고 한다. 하지만, ERD를 놓고 고객과 개발자가 치열하게 논의를 하는 경우를 보는 일은 어렵지 않다. UML은 결코 ERD보다 복잡하지 않다.

만일 UML로 작성된 모델이 실효성을 발휘하고 있지 못하다면, 본질적인 정보를 표현하는데 초점을 맞추기 보다는 산출물의 형식이나 모델링 방식에 얽매이는 수준에 머물러 있기 때문이 아닌가 생각해봐야 한다.

만일 고객이 이해할 수 있는 표현법이 클래스다이어그램 하나라면 이를 활용하여 의사소통을 하라. 많은 어휘와 수사를 활용한다고 의사소통이 잘 되는 것은 아니다.

모델 사이의 괴리를 줄여라

CBD 도입 초창기 EJB가 유행할 때 모델링 도구를 이용하여 EJB를 구성하는 요소들을 모두 설계 모델에 표현하던 때가 있었다. <그림 4>는 분석 모델에서 고작 네 개의 클래스 혹은 인터페이스를 EJB로 변환한 것이다. 이러한 모델은 EJB의 구성요소를 이해하는 것 이외에 어떤 효용성을 지닐지 의문이다.

<그림 4>의 다이어그램을 가지고 고객과 의사소통 할 수 있겠는가? 실제 현장에서는 이보다 훨씬 복잡하여 지하철 노선도와 같은 그림이 될지도 모른다.

고객과는 분석 모델로 의사소통을 하고, 설계 모델은 개발자를 위한 것이라고 가정해보자. 사실 고객 중에는 최종 사용자만 있는 것이 아니라, 시스템을 유지 보수하는 고객도 있다는 것을 고려하면 이러한 가정은 그다지 유효하지 않다. 그럼에도 불구하고 기술과 업무가 혼재되어 마치 스파게티와 같은 모델이 개발자에게라도 도움이 되는가?

필자가 참여했거나 알고 있던 모든 프로젝트는 분석 모델과 설계 모델을 별도로 만든다(현재도 대부분의 SI 프로젝트에서는 분석 모델과 설계 모델을 별도로 만든다). 분석/설계를 담당한 개발자들에게 UML로 모델링 하는 것을 멘토링 하는 것이 익숙해질 시점에서 한 가지 의문이 들었다.

촉박한 일정과 이제 막 UML을 배워서 모델링을 하는 개발자들이 분석 모델과 설계 모델을 모두 만들어내는 것이 과연 옳은가 하는 점이다(필자가 현재 참여하고 있는 프로젝트에서도 이러한 모순을 최대한 해결하려고 노력하고 있다).

더군다나 J2EE 기반의 애플리케이션을 만드는데 자바를 한 번도 써보지 않았고, CBD(Component-Based Development)의 기반기술에 대한 이해가 전혀 없는 사람이 업무 분석 이후에 설계를 담당했다.

결론적으로 필자는 분석 모델과 설계 모델을 모두 표현하는 방식에 매우 비효율적이라고 생각한다(아쉽게도 필자가 참여했던 프로젝트를 포함하여 대형 SI업체가 주도하는 대부분의 프로젝트에서는 분석 모델과 설계 모델을 모두 만들어낸다).

대체로 분석 모델을 만들 때는 업무에 초점이 맞춰진다. 분석 모델을 토대로 설계 모델을 만들어낸다. 설계 모델 작업은 대개 프로그래밍으로 만들기 위해서 영문화 작업을 하고 나서, 기술 환경을 위한 변형 작업을 수행한다.

이 때, 분석 내용에 누락된 것이나 미진한 사항이 있다면 어떻게 할 것인가? 또한, 새로운 요구사항이 들어오면 분석과 설계에 모두 적용할 것인가? 양쪽에 모두 반영하게 되면 주어진 시간에 대해 노력이 분산되고, 한쪽에만 반영하면 분석 모델과 설계 모델 사이의 연계가 완벽하게 유지되지 못한다.

분석 모델과 설계 모델의 통합

성공을 거두지는 못했지만 OMG의 MDA(Model Driven Architecture)는 고객과 애플리케이션 개발자 사이에서 하나의 모델(Platform Independent Model)만으로 의사소통 하는 방향을 지향했다. 이를 가능하도록 하기 위해 MDA 기반 실행 환경에서 구체적인 기술적 결정을 전담하게 했다.

MDA와는 완전히 다른 접근이지만, 최근에는 POJO(Plain Old Java Object) 기반의 개발 방식이 대두되면서 하나의 모델만으로도 고객과 개발자가 의사소통 할 수 있는 환경이 부상했다. 스프링(Spring)이라는 공개 소프트웨어가 MDA 실행환경과 유사한 역할을 제공하면서 실제 애플리케이션 코드와 분석 모델 사이의 차이가 매우 좁아졌다.

필자는 ERD가 고객과 통용이 되는 환경이라면, 적어도 UML로 작성한 클래스다이어그램으로 도메인의 핵심적인 어휘를 표현한다면 충분히 고객과 개발자가 업무에 관해 이야기 할 수 있다고 믿는다. 불필요한 정보나 표기법으로 복잡도만 가중시키지 않는다면, 고객이 클래스다이어그램을 가지고 이야기 하는 것에 흥미를 느낄 수도 있을 것이다.

또한, 고객과 개발자가 소통할 수 있다면 굳이 UML을 표기법으로 고집할 필요는 없다. RUP(Rational Unified Process)나 RUP에 기초한 방법론을 사용하는 경우에도 많은 경우, 비즈니스 모델링 산출물에는 UML을 굳이 쓰지 않는다. 이미 업무 흐름이나 주요 기능 구성을 표현하기 위해 고객들의 눈에 익은 표기법이 있기 때문이다.

하나의 모델을 향해 갈 때 만나게 되는 장벽

필자는 몇 년 전 분석 모델만을 사용하자는 의견을 제시한 일이 있다. 그리고 오랜 논의 끝에 분석 모델을 단지 영문으로 변환하는 수준에서 설계 모델을 만드는 방식으로 모델링 기법을 개선해나갔다. 이러한 과정 속에서도 많은 장벽을 마주치게 되었다. 주로 다음과 같은 반응이었다.

● 우리의 표준 방법론에 위배된다.

● 분석 모델과 설계 모델이 별로 차이가 없는 것이 말이 되느냐?

● 검증되지 않은 방법이다.

IT에도 일반 업무처럼 규정을 따르게 하는 조직의 운영방식이 투영된 것으로 해석할 수 있다. 혹은 아직 모델의 내용이나 효과를 논하는 수준이 되지 못하는 경우다. UML 모델을 처음 도입하는 시점에서 형식의 표준화로 최소한의 품질을 확보하려는 시점으로 볼 수 있다.

따라서 지나치게 형식에 얽매이는 경우를 아직은 어렵지 않게 만나게 된다. UML이 널리 쓰이고 있기 때문에 머지않아 이러한 문제는 결될 것이다.

이러한 장벽 이외에도 국내 언어 환경의 특수성에 기인한 문제도 넘어야 한다. 대부분의 국내 프로젝트에서 영어로 작성된 분석 모델은 상상하기는 힘들다. 반면에 설계 모델의 경우는 한글로 작성하면 코드와 대응시키기가 어렵다. 한글을 지원하는 프로그래밍 언어가 있다하더라도, 여전히 한글로 프로그래밍을 작성하는 경우는 찾아보기 힘들다.

소프트웨어 엔지니어는 앞서 언급한 장벽들을 해결하는 것을 업으로 한다. 뜻이 있는 곳에 길이 있다고 시간이 소요될 뿐 항상 해결책은 있기 마련이다.

먼저 새로운 방식에 대한 거부감이나 저항이 있는 경우라면 점진적으로 개선하면 된다. 분석 모델과 설계 모델 두 개를 모두 유지하더라도 도메인이 잘 드러나는 분석 모델을 중점적으로 활용하고, 설계 모델을 보조적으로 사용할 수도 있다. 또한, 분석 모델을 통해 코드를 도출하고, 역공학(reverse engineering)을 이용해 설계 모델을 만들 수도 있다.

DDD에서 말하듯이 하나의 언어로 모두에게 통용되면 좋겠지만 모든 상황에서 이를 적용할 수는 없다. 반면에 어디에서든 상황에 맞게 점진적으로 적용하는 것은 가능하다. 도메인 개념을 표현하는 방식 혹은 도메인 개념을 구체화하는 과정에서의 산출물 표기가 서너 가지 이상이라면 한 가지씩 줄여나가는 것만 해도 의사소통의 복잡도는 줄어드는 것이다.

새로운 방식에 대한 고객과 개발자의 적응을 돕기 위해서는 조심스러운 접근이 필요하다. 가시적인 실효성을 직접 맛보게 함으로써 변화를 적극적으로 수용하게 하는 것이다.

요즘 필자는 설계 모델 대신에 분석 모델로 포착한 업무 어휘를 엑셀 문서로 정리하고, 이를 기반으로 자바 클래스와 화면에 데이터를 전달할 XML 문서를 생성하는 작업을 시도하고 있다.

분석 모델이 갖는 약점을 설계 결정을 담은 엑셀 문서가 보완하는 방식이다. 개발 과정이나 향후 유지보수 시점에서 엑셀 시트가 익숙하게 통용될 수 있다면 굳이 UML만 활용할 필요는 없는 것 아닌가?

도메인 모델의 실효성을 극대화하기 위해서 모델과 실제 구현 산출물 사이의 괴리를 줄여야 한다. 그래야만 개발자들도 도메인 모델에 더욱 노력을 쏟을 수 있다. 소프트웨어 엔지니어는 이를 위해 지속적으로 프로세스나 개발 도구를 개선해야 한다.

<그림 7>에 나타낸 것처럼 도메인 모델로부터 많은 개발 산출물이 자동으로 생성될 수 있다면, 모델은 더욱 널리 쓰이게 되어 궁극인 하나의 언어로 나아갈 것이다.

한편, 분석 모델과 설계 모델의 차이가 한글과 영어라는 차이뿐이라면 굳이 두 개로 모델을 분리할 필요가 없다. EA(Enterprise Architect)와 같은 모델링 도구에서는 이름 외에도 별칭(Alias)을 추가로 지원한다. 이름은 한글을 사용하고, 별칭은 영어를 쓴다고 다이어그램에 따라서 한글로 보이게 하거나, 영문으로 나타낼 수 있다.

그런 기능을 지원하지 않는 모델링 도구를 쓴다고 해도 클래스 이름은 영문을 쓰고, 스테레오 타입에는 한글을 넣는 방법으로도 문제를 해결할 수 있다.

사용하는 언어가 다르다면 대화가 어려운 것은 상식적인 일이다. 언어가 같더라도 사용하는 어휘가 다르면 의사소통이 어렵기 마련이다. 고객이 원하는 시스템을 만들어내기 위해서 고객과 개발자는 충분한 대화 필요하고, 이를 통해 개발자는 고객의 요구를 충분하게 이해해야 한다.

소프트웨어 구현 기술은 비약적으로 발전해나가고 있지만, 고객의 요구사항도 따라서 복잡해져 가고 있다. 대부분의 프로젝트에서는 기술적인 문제로 실패하기 보다는 고객의 요구사항에 대한 낮은 이해가 실패의 원인으로 작용한다.

필자는 이 글에서 고객의 업무에 초점을 맞춘 도메인 모델이 갖는 의미를 강조하고자 했다. 도메인 모델의 고객과 개발자의 언어로서 통용되기 위해서는 지속적인 노력이 필요하다. 그러한 노력은 프로젝트의 성공을 위한 열쇠가 될 수 있다.

현실적으로 고객과 개발자, 그리고 서로 다른 유형의 개발자 사이에서 하나의 언어가 통용되게 하려면 많은 장벽을 넘어야 한다. 필자는 이 글에서 자세하게 이들 장벽을 살펴보지는 않았다. 사실 어떠한 장애물이 나타나도 그 상황에서 최적의 선택을 하면 그뿐이다.

짧은 글로 구체적인 실행 방안을 제공해주지는 못할 것이다. 그저 짧은 필력이나마 독자들에게 공통된 언어로써의 도메인 모델이 가치가 있다는 사실만 분명하게 전달할 수 있기를 바랄 뿐이다. @

참고자료

1. Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans, 33~34쪽.

2. http://www.agilemodeling.com/artifacts/classDiagram.htm

* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.