6. 객체 지도
유일하게 변하지 않는 것은 모든 것이 변한다는 사실뿐이다.
다른 사람에게 길을 물어보는 방법
- 정확한 설명, 기능적이고 해결책 지향적인 접근법 (일반적이거나 재사용 불가능)
- 지도를 통한 설명, 구조적이고 문제 지향적인 접근법
일반적으로 기능이 아닌 구조를 기반으로 설명하는 것이 이해하기 쉬우며 안정적입니다.
- 전통적인 소프트웨어 개발방법은 기능적인 방향이었으나 객체지향 개발 방법은 안정적인 구조이며 범용적이고 재사용성이 높으며, 변경에 안정적입니다.
아래에서는 기능이 아닌 구조를 바탕으로 시스템을 분할하는 객체지향의 또 다른 측면에 관해 설명합니다.
#
6.1 기능 설계 대 구조 설계모든 소프트웨어 제품의 설계는 두 가지 측면이 존재합니다. 하나는 기능(function)이고 하나는 구조(structure) 측면의 설계입니다.
- 훌륭한 기능이 훌륭한 소프트웨어를 만드는 충분조건이라고 한다면 훌륭한 구조는 훌륭한 소프트웨어를 만들기 위한 필요조건입니다.
- 깔끔하고 단순하며 유지보수하기 쉬운 설계는 사용자의 변하는 요구사항을 반영할 수 있도록 쉽게 확장 가능한 소프트웨어를 창조할 수 있는 기반이 됩니다.
- 설계가 어려운 이유는 요구사항이 변경될 수 있기에 그러한 요구사항도 수용할 수 있는 코드를 재창조해야하기 때문입니다.
- 미래에 대비하는 가장 좋은 방법은 변경을 예측하는 것이 아닌 변경을 수용할 수 있는 선택의 여지를 주는 것입니다.
#
6.2 두 가지 재료: 기능과 구조객체지향에서 기능과 구조를 표현하기 위해 일관되게 적용할 수 잇는 두가지 기법은 다음과 같습니다.
- 구조는 사용자나 이해관계자들이 도메인(domain)에 관해 생각하는 개념과 개념들 간의 관계로 표현합니다.
- 기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위로 표현합니다.
일반적으로 기능을 수집하고 표현하기 위한 기법을 유스케이스 모델링이라고 하고, 구조를 수집하고 표현하기 위한 기법을 도메인 모델링이라고 합니다.
#
6.3 안정적인 재료 : 구조#
도메인 모델- 도메인 : 사용자가 프로그램을 사용하는 대상 분야
- 도메인 모델 : 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태입니다.
- 도메인 모델은 이해관계자를 바라보는 멘탈 모델(Mental Model)입니다.
- 도메인 모델은 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지를 포괄하도록 추상화한 소프트웨어 모델입니다.
#
도메인의 모습을 담을 수 있는 객체 지향- 최종 코드는 사용자가 도메인을 바라보는 관점을 반영해야합니다. 즉, 애플리케이션이 도메인 모델을 기반으로 설계해야합니다.
- 객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지가 모두 유사한 모습을 유지하도록 만드는 것이 가능하며 이러한 특징을 연결완전성 또는 표현적 차이라고 합니다.
#
표현적 차이- 소프트웨어 객체와 현실 객체 사이의 관계는 은유에 가깝습니다.
- 소프트웨어 객체와 현실 객체 사이의 의미적 거리를 가리켜 표현적 차이 또는 의미적 차이라고 합니다.
- 도메인 모델을 기반으로 설계하고 구현하는 것은 사용자가 도메인을 보는 관점을 코드에 반영하게 되고, 표현적 차이는 줄어들어 소프트웨이를 이해하고 수정하기 쉽게 만들어줍니다.
#
불안정한 기능을 담는 안정적인 도메인 모델- 도메인 모델이 제공하는 구조는 상대적으로 안정적입니다.
- 본질적이라는 의미는 변경이 적고 비교적 그 특성이 오랜 시간 유지됨을 의미합니다. 이러한 본질적인 부분에 기반한 설계와 코드는 변경에 쉽게 대처가 가능합니다.
- 안정적인 구조를 제공하는 도메인 모델을 기반으로 소프트웨어의 구조를 설계하면 변경에 유연하게 대응할 수 있는 탄력적인 소프트웨어를 만들 수 있습니다.
- 다만, 도메인 모델이 도메인과 관련된 중요한 개념과 관계를 보여줘도 실제 사용자에게 중요한 것은 도메인 모델이 아닌 소프트웨어 기능입니다.
- 객체지향에서 소프트웨어의 기능을 기술하기 위해 유스케이스를 사용합니다.
#
6.4 불안정한 재료 : 기능#
유스케이스유스케이스 : 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것
- 사용자는 자신의 목표를 달성하기 위해 시스템과의 상호작용을 시작합니다.
- 유스케이스의 가치는 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있습니다.
#
유스케이스의 특성유스케이스의 중요 특성은 다음과 같습니다.
- 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 '텍스트'입니다.
- 유스케이스는 다이어그램이 아니며, 중요한 것은 상호작용의 흐름입니다.
- 유스케이스는 하나의 시나리오가 아니라 여러 시나리오들의 집합입니다
- 유스케이스는 하나의 시나리오가 아닌 시나리오의 집합이며, 이러한 시나리오를 유스케이스 인스턴스 (use-case instance) 라고 합니다.
- 유스케이스는 단순한 피처 목록과 다릅니다.
- 피처는 시스템이 수행해야 하는 기능의 목록을 나열한 것입니다.
- 유스케이스의 강점은 유스케이스가 단순히 기능을 나열하는 것이 아니라 이야기를 통해 연관된 기능들을 함께 묶을 수 있는 점입니다.
- 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 합니다.
- 본질적인 유스케이스 : 사용자 인터페이스를 배제한 유스케이스 형식
- 유스케이스는 내부 설계와 관련된 정보를 포함하지 않습니다.
- 유스케이스의 목적은 연관된 시스템의 기능을 이야기 형식으로 모으는 것이며 내부 설계를 설명하는 것은 아닙니다.
- 유스케이스의 객체 설계는 공학적 규칙과 원칙이 아닌 경험과 상식, 의사소통을 기반으로 한 창조 작업입니다.
#
유스케이스는 설계 기법도, 객체지향 기법도 아니다- 유스케이스는 사용자가 바라보는 시스템의 외부 관점만을 표현합니다.
- 유스케이슨느 시스템이 외부에 제공해야 하는 행위만 포함하므로 시스템의 내부 구조를 유추할 수 없습니다.
- 유스케이스와 객체의 구조 사이는 큰 간격이 존재합니다.
- 유스케이스를 통해 도메인 모델에서 사용할 용어를 얻을 수도 있습니다.
#
6.5 재료 합치기 : 기능과 구조의 통합#
도메인 모델, 유스케이스, 그리고 책임-주도 설계- 객체지향에서는 불안정한 기능을 안정적인 구조에 담음으로써 변경에 대한 파급효과를 줄여야합니다.
- 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배합니다.
- 객체지향은 객체에서 시작됩니다.
- 시스템이라는 객체 안에는 더 작은 규모의 객체가 포함됩니다.
- 시스템에 할당된 커다란 책임은 이제 시스템 안의 작은 규모의 객체들이 수행해야 하는 더 작은 큐모의 책임으로 세분화합니다.
- 유스케이스는 사용자에게 제공할 기능을 시스템의 책임으로 보게 함으로써 객체 간의 안정적인 구조에 책임을 분배할 수 있는 출발점을 제공합니다.
- 책임-주도 설계 방법은 시스템의 기능을 역할과 책임을 수행하는 객체들의 협력 관계로 바라보게 함으로써 유스케이스와 도메인 모델을 통합합니다.
- 유스케이스에서 출발해 객체들의 협력으로 이어지는 흐름은 객체 안에 다른 객체를 포함하는 재귀적 합성이라는 객체지향의 기본 개념을 잘 보여줍니다.
스몰토크의 설계는 우리가 설명할 수 있는 모든 것이 상태와 처리 과정을 내부로 은닉하는 행위적 빌딩블록의 재귀적인 합성(recursive composition)으로 표현할 수 있으며, 메시지의 교환을 통해서 빌딩 블록들을 처리할 수 있습니다.
#
기능 변경을 흡수하는 안정적인 구조- 도메인 모델을 기반으로 객체 구조를 설계하는 이유는 도메인 모델이 안정적이기 때무닙니다.
- 도메인 모델의 특징은 도메인 모델을 중심으로 객체 구조를 설계하고 유스케이스의 기능을 객체의 책임으로 분배하는 기본적 객체지향 설계방식의 유연함을 잘 보여줍니다.
- 객체지향의 가장 큰 장점은 도메인을 모델링하기 위한 기법과 도메인을 프로그래밍하기 위해 사용하는 기법이 동일합니다.
- 객체 지향이 강력한 이유는 연결완전성의 역방향 역시 성립해서입니다. (이러한 모델의 부드러운 흐름을 가역성(reversibility) 라고 합니다.)
- 안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하고 도메인 모델과 코드를 밀접하게 연관시키는 것이 중요합니다. 이것이 유지보수가 쉽고 유연한 객체지향 시스템을 만들게 됩니다.