2009년 11월 06일
유연한 설계를 위한 패턴과 원리 - 1.시간, 돈, 그리고 GENERIC SUBDOMAIN 2부
반복과 리팩토링
Domain-Driven Design의 용어를 빌자면 도메인 영역 내에서 관심사를 분리하는 것을 증류(distillation)라고 한다. 모델이란 지식을 증류시켜 불필요한 부분이 제거된 순수한 상태로 만든 것이다. 여기 저기 흩어져 있는 도메인 지식을 깊이 있는 통찰을 반영한 모델로 증류시키기 위해서는 해당 도메인을 학습하는 개발자와 도메인 전문가의 긴밀한 참여와 함께 반복적인 리팩토링 과정이 수반되어야 한다.
리팩토링이란 소프트웨어를 보다 쉽게 이해할 수 있고 적은 비용으로 수정할 수 있도록 외부에 보이는 동작의 변화 없이 내부 구조를 변경하는 것을 의미한다. 예언자로서의 자질을 요구하는 사전 설계(up-front design)와 달리 리팩토링은 현재 알고 있는 지식을 바탕으로 가장 단순하지만 최선의 설계를 할 수 있는 길로 우리를 인도한다.
코드에 버그를 삽입하지 않고 안전하게 리팩토링을 완료하기 위해서는 스스로 검증 가능한 테스트 케이스를 구비하여 안전망을 갖추는 것이 필수적이다. 테스트 케이스는 코드를 작성한 후보다는 작성하기 전에 개발하는 것이 더 효율적이다. 실패하는 테스트를 추가하고, 테스트를 성공시키도록 코드를 수정한 후, 최종적으로 리팩토링을 통해 중복을 제거한다. 이처럼 테스트를 먼저 작성해서 코드의 설계를 이끌어 가는 방식을 테스트 주도 개발(TDD)이라고 한다.
리팩토링과 TDD는 반복(iteration)과 함께 버무려져야 그 진가를 발휘한다. 소프트웨어 라이프 사이클을 작은 반복 단계로 나누고 각 반복 단계에서 소프트웨어의 증분을 개발함으로써 개발팀은 피드백을 얻을 수 있다. 반복은 사전 설계의 압력을 완화시켜 책임이 따르는 마지막 순간까지 결정을 미룰 수 있도록 한다. 반복 단계를 통해 모든 것이 명확해 지고 도메인에 대한, 또는 코드에 대한 깊은 통찰을 얻게 되면 언제라도 리팩토링을 통해 코드와 모델을 개선할 수 있고, TDD를 통해 모든 것이 안전하다는 확신을 가질 수 있다. 이것이 바로 가장 유명한 애자일 방법론인 XP의 모토인 ‘언제나 설계하라’를 가능하게 하는 기반 요소다.
일반적인 리팩토링 카탈로그는 기술적인 부분에 초점을 맞춘다. 마이크로 리팩토링과 패턴을 향한 리팩토링이 가장 대표적인 기술적인 리팩토링 범주다. 그러나 다른 한편에 기술적인 압력이 아닌 새롭게 얻어진 도메인에 대한 통찰을 반영하기 위한 리팩토링이 존재한다. 이를 심도 깊은 모델을 향한 리팩토링(refactoring to a deeper model)이라고 부른다.
리팩토링이 가능하기 위해서는 설계가 유연해야 한다. 유연한 설계의 배후에는 낮은 결합도와 높은 응집도와 같은 기술적인 이슈뿐만 아니라 도메인에 포함된 개념들을 단순하고 명확한 방식으로 전달해야 한다는 도메인 이슈도 포함된다.
그래도 역시 시간은 돈이다.
거의 모든 엔터프라이즈 애플리케이션의 GENERIC SUBDOMAIN에는 시간과 돈이 포함된다. 그럼에도 불구하고 애플리케이션 개발에 사용되고 있는 대부분의 언어가 제공하는 시간과 돈에 관한 라이브러리의 기능이 미미하다는 점은 아이러니가 아닐 수 없다. Evans는 이런 문제점을 해결하기 위해 저서인 Domain-Driven Design에서 소개한 설계 원리와 패턴을 적용하여 TimeAndMoney 라이브러리를 개발하기도 했다. TimeAndMoney는 시간과 돈에 관련된 다양한 기능들을 도메인 요구사항에 가깝게 기술할 수 있도록 하기 위해 Java 기반의 내부 DSL(Internal Domain-Specific Language) 형태로 구현한 라이브러리다.
본 연재에서는 Eric Evans의 TimeAndMoney 라이브러리의 기본 개념과 구조, 개발 원리를 차용하여 유사한 형태의 GENERIC SUBDOMAIN을 리팩토링과 TDD를 통해 작성함으로써 명확하고 유연한 설계를 만들기 위한 원칙과 패턴을 설명하기로 한다. 노파심에 하는 말이지만 필자를 NIH(Not-Invented Here) 증후군 중독자로 보지 말아주었으면 한다.
GENERIC SUBDOMAIN은 CORE DOMAIN의 요구사항에 의해 주도된다. GENERIC SUBDOMAIN은 재사용 라이브러리가 아니다. 따라서 GENERIC SUBDOMAIN을 설명하기 위해서는 가상의 CORE DOMAIN이 필요하다. 여기에서는 간단한 가상의 핸드폰 과금 시스템을 통해 GENERIC SUBDOMAIN에 포함될 기능들을 단계적으로 구현해 볼 것이다.
통신사의 로밍 서비스를 사용한 경우의 다중 통화 문제를 해결하기 위해 리팩토링과 TDD를 적용하여 GENERIC SUBDOMAIN의 모델을 작성하는 부분에서 시작할 것이다. 다중 통화 문제를 선언적인 방식으로 구현하기 위해 적용된 패턴을 설명한 후 이를 적용하여 시간대를 처리하는 두 번째 GENERIC SUBDOMAIN을 구현해 볼 것이다. 돈과 관련된 첫 번째 GENERIC SUBDOMAIN을 설명할 때에는 리팩토링과 TDD의 리듬을 전달하는데 주력할 것이며, 시간과 관련된 두 번째 GENERIC SUBDOMAIN을 설명할 때에는 유연한 설계로 이끄는 개별 패턴에 초점을 두어 설명할 것이다.
비록 시간이 돈이라고는 하지만 손에 잡히지 않는 시간보다는 주머니 속의 현찰이 더 궁한 신세다 보니 시간은 잠시 뒤로 미루어 두고 돈 문제부터 해결하기로 하자.
이 글과 관련있는 글을 자동검색한 결과입니다 [?]
# by | 2009/11/06 20:49 | Supple Design | 트랙백 | 덧글(2)




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
한 가지 주의하실 점은 GENERIC SUBDOMAIN은 재사용 가능한 라이브러리는 아니라는 점입니다. GENERIC SUBDOMAIN은 해당 도메인의 CORE DOMAIN에 속하지 않는 도메인 개념일 뿐 다른 도메인에서 재사용가능하지 않을 수도 있습니다.