6. 도메인과 구조, 유스케이스와 기능
목적지를 찾아 가는 방법은 크게 두 가지로 나뉜다.
첫 번째는 다른 사람에게 길을 물어보는 방법이고, 두 번째는 지도를 이용해 길을 찾는 방법이다.
전자는 기능적이고 해결책 지향적인 접근법으로 재사용이 불가능하고, 후자는 구조적이고 문제 지향적인 접근법으로 재사용이 가능하다.
즉, 지도는 현실세계의 지형을 기반으로 한 추상모델이다.
이 비유의 핵심은 기능이 아니라 구조를 기반으로 모델을 구축하는 것이 좀 더 범용적이며 이해하기 쉬우며 변경에 안정적이라는 것이다.
전통적인 소프트웨어 개발 방법은 변경이 빈번하게 발생하는 기능에 안정적인 구조를 종속시키는 “길을 묻는” 방법도 유사하며,
객체지향 개발 방법은 안정적인 구조에 변경이 빈번하게 발생하는 기능을 종속시키는 “지도”의 방법과 유사하다.
본 포스팅에서는 기능이 아니라 구조를 바탕으로 시스템을 분할하는 객체지향의 또 다른 측면에 관해 다룬다.
자주 변경되는 기능이 아닌, 안정적인 구조를 기반으로 시스템을 분할하는 객체지향적인 접근법은
역할, 책임, 협력을 기반으로 시스템의 기능을 구현하는 책임-주도 설계의 본질을 이해하는 데 도움이 될 것이다.
6.1. 기능 측면의 설계
모든 소프트웨어 제품의 설계에는 기능 측면의 설계와 구조 측면의 설계라는 두 가지 측면이 존재한다.
기능 측면의 설계는 제품이 사용자를 위해 무엇을 할 수 있는지에 초점을 맞춘다.
소프트웨어라는 제품 자체가 사용자가 필요로 하는 기능을 제공하기에 가치를 지닌 것인만큼
개발 초기단계에서는 사용자가 무엇을 원하는지, 그리고 사용자가 원하는 것을 만족시키기 위해 어떤 기능을 제공해야하는지에 집중해야 한다.
최종적으로 기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위료 표현되어야 한다.
6.2. 구조 측면의 설계
기능 측면의 설계와 달리 구조 측면의 설계는 제품의 형태가 어떠해야하는 지에 초점을 맞춘다.
사용자가 원하는 기능을 그대로 제공하면서, 새로운 요구사항을 빠르고 안정적으로 추가하기위해서 깔끔하고 단순하며 유지보수하기 쉬운 설계를 가지고 있어야 한다.
문제는 새로운 요구사항이라는 것은 미래의 일이기 때문에 예측이 불가능한 것이 문제다.
따라서 가장 좋은 선택지는 변경을 수용할 수 있는 선택의 여지를 설계에 마련해놓는 것이다.
결국 좋은 설계란 나중에라도 변경할 수 있는 여지를 남기는 설계이며, 이 설계의 목적은 추후 추가되는 기능을 허용하고 변경에 소요되는 비용을 낮추는 것이다.
최종적으로 구조는 사용자나 이해관계자들이 도메인에 관해 생각하는 개념과 개념들 간의 관계로 표현되어야 한다.
6.3. 구조 : 도메인과 모델
먼저 도메인과 모델을 각각 정의해보자.
소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정한 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인(domain) 이라고 한다.
모델이란 대상을 단순화해서 표현한 것으로, 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태 를 의미한다.
즉, 모델을 복잡성을 관리하기 위해 사용하는 기본적인 도구이다.
이제 도메인과 모델을 연결하여 도메인 모델을 정의해보자.
도메인 모델 이란 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다.
도메인 모델은 소프트웨어가 목적하는 영역내의 개념과 개념과의 관계, 다양한 규칙이나 제약 등을 추상화한 것이다.
도메인 모델은 단순히 다이어그램이 아닌, 이해 관계자들이 바라보는 멘탈 모델(Mental Model) 이며,
자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다.
사용자들은 자신의 멘탈 모델과 유사한 방식으로 제품이 반응하고 움직일 것이라고 기대하기 때문에, 훌륭한 디자인이란 사용자가 예상하는 방식에 따라 정확하게 반응하는 제품을 만드는 것이다.
여기서 멘탈 모델은 사용자 모델, 디자인 모델, 시스템 이미지의 3종류로 구분할 수 있다.
- 사용자 모델 : 사용자가 제품에 대해 가지고 있는 개념들의 모습
- 디자인 모델 : 설계자가 마음 속에 가지고 있는 시스템에 대한 개념화
- 시스템 이미지 : 최종 제품
이상적인 경우는 사용자 모델과 디자인 모델이 일치하는 경우이다.
다만 사용자와 설계자는 직접적으로 상호작용할 수 없고, 시스템를 통해서만 간접적으로 의사소통할 수 있으므로 시스템 이미지가 사용자 모델을 정확하게 반영하도록 노력해야한다.
결과적으로 도메인 모델은 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지를 포괄하도록 추상화한 소프트웨어 모델이다.
따라서, 도메인 모델은 소프트웨어에 대한 멘탈 모델로 귀결된다.
객체지향은 이 도메인 모델의 세 가지 측면을 모두 모델링할 수 있는 거의 유일한 모델링 패러다임이다.
객체지향을 사용하면 사용자들이 이해하고 있는 도메인의 구조와 최대한 유사하게 코드를 구조화할 수 있다.
객체지향의 이러한 특징을 연결 완전성 또는 표현적 차이 라고 한다.
이 표현적 차이는 현실 객체의 특성을 토대로 구축된 소프트웨어 객체와의 차이를 의미하며 다른 말로 의미적 차이(semantic gap) 라고도 한다.
여기서의 핵심은 은유를 통해 현실 객체와 소프트웨어 객체 사이의 갭을 최대한 줄여나가는 것이다.
따라서 소프트웨어 객체는 현실성을 따지지않고 도메인 모델을 통해 표현되는 도메인 객체들을 은유해야 한다.
6.4. 기능 : 유스케이스
시스템이 사용자에게 기능을 제공하는 이유는 사용자들이 시스템을 통해 달성하고자 하는 목표가 있기 때문이다.
따라서 훌륭한 기능적 요구사항을 얻기 위해서는 목표를 가진 사용자와 사용자의 목표를 만족시키기 위한 일련을 절차를 수행하는
시스템 간의 상호작용 관점에서 시스템을 바라보아야 한다.
이 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스(usecase) 라고 한다.
앨리스터 코오번(Alistair Cockburn)은 유스케이스를 아래와 같이 설명하였다.
유스케이스는 시스템의 이해관계자들 간의 계약을 행위 중심으로 파악한다.
유스케이스는 이해관계자들 중에서 일차 액터(primary actor) 라 불리는 행위자의 요청에 대한 시스템의 응답으로서, 다양한 조건하에 있는 시스템의 행위를 서술한다.
일차 액터란 시스템의 서비스 중 하나를 요청하는 이해관계자로, 하나의 목표를 가지고 유스케이스를 시작하는 액터를 의미하며,
일반적으로 시스템과 연동하는 외부 시스템 역시 일차 액터의 범주에 포함시킨다.
이 유스케이스의 가치를 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다.
여기저기 흩어져있는 기능에 사용자의 목표라는 문맥을 제공함으로써, 각 기능을 유기적으로 연결해줄 수 있게 한다.
이제 유스케이스의 특성을 알아보자.
유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 텍스트다.
중요한 것은 유스케이스가 표현하는 상호작용의 흐름이며, 사용자와 시스템 간의 상호작용을 일련의 이야기 흐름으로 표현하는 것이다.유스케이스는 하나의 시나리오가 아닌 여러 시나리오들의 집합이다.
유스케이스는 단순한 기능의 목록과는 다르다.
유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 않는다.
유스케이스는 자주 변경되는 사용자 인터페이스 요소는 배제하고 사용자 관점에서 시스템의 행위에 초점을 맞추어야 한다.유스케이스는 내부 설계와 관련된 정보를 포함해선 안된다.
유스케이스의 목적은 시스템의 기능을 이야기 형식으로 모으는 것이지, 내부 설계의 명세가 아니다.
6.5. 구조와 기능의 통합
훌륭한 객체지향 설계란 불안정한 기능을 안정적인 구조안에 담음으로써, 변경에 대한 파급효과를 최소화하는 것이다.
도메인 모델은 안정적인 구조를 개념화하고, 유스케이스는 불안정한 기능을 서술하기 위해 사용되는 도구로,
유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배하여 변경에 유연한 소프트웨어를 개발해야 한다.