들어가기 전
지금까지는 애플리케이션을 만들 때, 다른 사람들이 해놓은 설계를 기반으로 만들거나 그냥 주먹구구식으로 필요할 것 같은 클래스를 만들고 그 안에 속성, 기능이 무엇일지 생각했던 것 같다. 『객체지향의 사실과 오해』를 읽다보니 도메인 모델과 유스케이스라는 개념이 나오는데, 애플리케이션 제대로 설계하려면 꼭 알고있어야하는 개념인 것 같아 정리해보려고 한다.
도메인 모델
시스템을 ‘기능’과 ‘구조’의 관점에서 생각했을 때, 도메인 모델은 시스템의 구조를 표현하기 위한 수단이다. 도메인이란 ‘사용자가 프로그램을 사용하는 대상 분야’를 의미한다. 도메인의 쉬운 예로 금융, 게임, 쇼핑 등이 있을 것이다.
도메인 모델 = 도메인 + 모델
- 모델은 어떤 대상을 추상화하고 단순화한 것이다.
- 따라서 도메인 모델은 도메인과 관련된 부분을 추상화한 것이다.
- 도메인과 관련되지 않은 사항들에 대해서는 무시함으로써, 현실 세계의 복잡성을 관리할 수 있다.
- 도메인 모델에는 도메인과 관련된 이해관계자들이 도메인에 대해 생각하는 관점이 반영되어야 한다.
- 즉, 도메인 모델은 이해관계자들이 해당 도메인을 바라보는 멘탈 모델(Mental Model)이다.
- 멘탈 모델이란 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다.
- 사용자들은 자신이 이용하는 시스템이 자신의 멘탈 모델과 유사한 방식으로 작동할 것으로 기대한다.
- 따라서 좋은 시스템 디자인이란 사용자가 예상하는 방식으로 반응하는 제품을 만드는 것이다.
도메인 모델과 객체지향
위에서 살펴본 것 처럼 우리가 만들 시스템(최종 제품)에는 도메인에 대한 사용자 관점이 반영되어야 한다. 이를 소프트웨어 개발 관점에서 생각해보면, 애플리케이션은 도메인 모델을 기반으로 설계되어야 한다는 것을 의미한다.
- 객체지향 패러다임은 사용자가 도메인을 바라보는 관점 / 설계자가 시스템 구조를 바라보는 관점 / 구현된 코드의 모습을 모두 모델링 할 수 있는 강력한 모델링 패러다임이다.
- 즉 객체지향 패러다임은 사용자 관점, 설계자 관점, 코드의 모습을 모두 유사한 형태로 유지할 수 있게 하는 사고도구와 프로그래밍 기법을 제공한다.
표현적 차이
소프트웨어 객체는 현실 객체에 대한 추상화가 아니다. 즉, 소프트웨어 객체는 현실 객체를 모방한 것이 아니라 은유를 기반으로 재창조한 것이다. 따라서, 소프트웨어 객체는 현실 객체가 갖지 못한 특성을 가질 수도 있고, 현실 객체가 하지 못하는 행동을 할 수도 있다.
은유(metaphor) : 경험, 생각, 감정, 행동 또는 대상 간의 유사성을 암시하는 상징적인 접근 방식
- 표현적 차이(의미적 차이)
- 소프트웨어 객체와 현실 객체 사이의 의미적 거리이다.
- 도메인 모델이 중요한 이유는 은유를 통해 표현적 차이를 줄일 수 있기 때문이다.
- 즉, 사용자의 멘탈 모델이 코드에 더 잘 녹아들 수 있다.
- 결과적으로 표현적 차이가 줄어들수록 코드의 구조가 도메인의 구조를 잘 반영하게된다.
- 이를 통해 이해하고 수정하기 쉬운 소프트웨어를 만들 수 있다.
안정적인 도메인 모델
도메인 모델을 기반으로 코드를 작성하면 상대적으로 안정적인 구조를 만들 수 있다.
- 도메인 모델에 도메인에 대한 사용자의 관점을 반영해야 하는 이유는 사용자들이 도메인의 본질에 대해 가장 잘 이해하기 때문이다.
- 본질은 변경이 적고 비교적 그 특성이 오랜 시간 유지된다는 것을 의미한다.
- 소프트웨어를 개발하고 유지보수함에 있어서 변경은 피할 수 없는 숙명같은 것이다.
- 하지만, 도메인 모델에 포함된 개념과 규칙은 도메인의 ‘본질’을 다루기 때문에 변경될 확률이 적다.
- 변경된다 하더라도 변경에 쉽게 대처할 수 있을 가능성이 커진다.
- 도메인 모델을 기반으로 소프트웨어 구조를 설계하면, 안정적인 구조 위에 (비교적) 자주 변경되는 기능을 배치할 수 있다.
- 이와 같은 설계는 변경에 유연한 소프트웨어를 만들 수 있게 해준다.
유스케이스
소프트웨어의 존재 이유는 사용자가 원하는 기능을 제공하기 위함이다. 유스케이스는 사용자와 시스템 간의 상호작용 흐름을 텍스트로 정리한 것이다.
- 유스케이스의 가치는 사용자 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다.
- 즉, 사용자 목표를 통해 각각의 기능을 유기적인 관계를 지닌 체계로 발전시킨다.
유스케이스의 특성
1. 유스케이스는 사용자와 시스템간의 상호작용을 나타내는 ‘텍스트’이다.
- 유스케이스의 핵심은 다이어그램이 아닌 사용자와 시스템 간의 상호작용을 이야기 흐름으로 표현하는 것이다.
2. 유스케이스는 여러 시나리오들의 집합이다.
- 예를 들어, ‘이자 계산’이라는 유스케이스는 다음 두 개의 시나리오로 구성할 수 있다.
- 예금주가 계좌를 선택하고 당일까지의 이자액을 계산
- 예금주가 계좌를 선택하고 특정 일자까지의 이자액을 계산
- 즉, 유스케이스는 특정한 사용자의 목표(위 예시에선 이자 계산)와 관련된 모든 시나리오의 집합이다.
3. 유스케이스는 단순한 기능 목록이 아니다.
- 기능만 나열하는 것은 각각의 기능을 서로 연관이 없는 것처럼 보이게 만든다.
시스템은 정기예금 정보를 보여준다
,시스템은 당일이나 현재 일자의 이자를 계산한다
라는 두 기능을 중도 해지 이자액을 계산한다라는 유스케이스로 묶을 수 있다.- 이를 통해, 시스템의 기능에 대해 의사소통할 수 있는 문맥을 얻을 수 있다.
4. 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.
- 자주 변경되는 사용자 인터페이스 요소는 배제하고, 사용자 관점에서 시스템의 행위에 초첨을 맞춘다.
5. 유스케이스는 내부 설계와 관련된 정보를 포함하지 않는다.
- 유스케이스의 목적은 내부 설계를 설명하는 것이 아니다.
- 과거에는 유스케이스에 나타나는 명사를 클래스로, 동사를 메서드로 대응시키는 방식으로 객체지향 설계를 설명하기도 했지만 객체지향 설계는 이렇게 단순하지 않다.
- 유스케이스에서 객체 설계로의 전환은 경험, 상식, 의사소통을 기반으로 한 창조 작업이다.
- 물론 유스케이스 안에서 도메인 모델에 사용할 용어에 대한 힌트를 얻을 수도 있다.
- 하지만 유스케이스 안에 도메인 모델을 구축할 수 있는 모든 정보가 포함되어 있진 않다.
기능과 구조의 통합
변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야 한다.
책임 주도 설계
책임 주도 설계 방법은 시스템의 기능을 역할과 책임을 수행하는 객체들의 협력 관계로 바라볼 수 있게 한다. 이를 통해 유스케이스와 도메인 모델을 통합한다.
- 사용자의 관점에서 시스템은 자신이 전송한 메시지에 응답하는 데 필요한 책임을 수행하는 일종의 객체다.
- 시스템이 수행해야 하는 커다란 규모의 책임은 더 작은 크기의 객체들의 협력을 통해 구현될 수 있다.
- 객체들을 식별함에 있어 도메인 모델을 사용할 수 있다.
- 유스케이스를 통해 협력을 완성하는 데 필요한 메시지를 식별하면서 객체들에게 책임을 할당한다.
- 결과적으로, 코드는 불안정한 기능을 수용할 수 있는 안정적인 구조가 된다.