6장. 객체 지도
어떤 목적지를 찾아서 가는 방법은 다음과 같이 두 가지로 나눌 수 있다.
다른 사람에게 길을 물어보는 방식인 기능적이고 해결책 지향적인 접근법(functional, solution-directed approach)
일반적이지도, 재사용 가능하지도 않다.
설명만으로 경로를 찾기도 쉽지 않다.
지도를 이용하는 방식인 구조적이고 문제 지향적인 접근법(structural, problem-directed approach)
길을 찾는 데 필요한 '기능'이 아닌 '구조'를 제공한다.
현재의 목적뿐만 아니라 다양한 목적을 위해 재사용될 수 있듯이 범용적이다.
지도 은유의 핵심은 기능이 아니라 구조를 기반으로 모델을 구축하는 편이 좀 더 범용적이고 이해하기 쉬우며 변경에 안정적이라는 것이다. 사람들의 요구사항은 계속 변하기 때문에 모델이 제공해야 하는 기능 역시 지속적으로 변할 수 밖에 없다.
객체 지향도 이와 유사하다. 자주 변경되는 기능이 아니라 범용적이고, 재사용성이 높으며, 변경에 안정적인 구조를 기반으로 시스템을 구조화 한다.
기능 설계 대 구조 설계
모든 소프트웨어 제품의 설계에는 두 가지 측면이 존재한다.
기능(function) 측면의 설계
제품이 사용자를 위해 무엇을 할 수 있는지에 초점을 맞춘다.
구조(structure) 측면의 설계
제품의 형태가 어떠해야 하는지에 초점을 맞춘다.
설계의 가장 큰 도전은 기능과 구조라는 두 가지 측면을 함께 녹여 조화를 이루도록 만드는 것이다.
훌륭한 기능이 훌륭한 소프트웨어를 만드는 충분조건이라고 한다면
훌륭한 구조는 훌륭한 소프트웨어를 만들기 위한 필요조건이다.
소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다. 설계라는 행위를 중요하게 만드는 것은 변경에 대한 필요성이다.
좋은 설계란 유연하게 변경사항에 대응하는 것을 의미하는 것 같다.
두 가지 재료: 기능과 구조
객체지향 세계를 구축하기 위해서는 사용자에게 제공할 '기능'과 기능을 담을 안정적인 '구조'라는 재료가 준비돼 있어야 한다.
기능: 사용자가 자신의 목표를 달성하기 위해 사용할 수 있는 시스템의 서비스
구조: 시스템의 기능을 구현하기 위한 기반으로, 기능 변경을 수용할 수 있도록 안정적이어야 함.
이 두 가지 재료를 구하는 방법이 중요하다.
구조는 사용자나 이해관계자들이 도메인(domain)에 관해 생각하는 개념과 개념들 간의 관계로 표헌한다.
도메인 모델링 기법
기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위로 표헌한다.
유스케이스 모델링 기법
안정적인 재료: 구조
도메인 모델
모든 소프트웨어는 사용자의 '필요성'을 충족시키기 위해 존재한다. 소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정한 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인 이라고 한다.
도메인 모델에서의 모델은 대상을 단순화해서 표헌한 것을 말한다.
지식을 선택적으로 단순화하고 의식적으로 구조화한 형태
대상을 추상화하고 단순화한 것
복잡성을 관리하기 위해 사용하는 기본적인 도구
도메인 모델
이 두가지를 합쳐 도메인 모델이라 한다. 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태를 도메인 모델이라고 한다.
소프트웨어가 목적하는 영역 내의 개념과 개념 간의 관계, 다양한 규칙이나 제약 등을 추상화한 것
소프트웨어 개발과 관련된 이해관계자들이 도메인에 대해 생각하는 관점
소프트웨어의 도메인이 무엇이건 상관없이 그곳에는 항상 도메인과 관련된 사람들이 도메인을 바라보는 모델이 존재한다.
도메인 모델은 이해관계자들이 바라보는 멘탈 모델(Mental Model)이다. 멘탈 모델이란 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다. 소프트웨어 사용자들은 도메인에 존재하는 현상을 이해하고 현상에 반응하기 위해 도메인과 관련된 멘탈 모델을 형성한다.
제품을 설계할 때 제품에 관한 모든 것이 사용자들이 제품에 대해 가지고 있는 멘탈 모델과 정확하게 일치해야 좋은 제품이라고 볼 수 있다.
도메인 모델은 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지를 포괄하도록 추상화한 소프트웨어 모델로 소프트웨어에 대한 멘탈 모델이라고 할 수 있다.
도메인의 모습을 담을 수 있는 객체 지향
최종 제품은 사용자의 관점을 반영해야 한다는 것이다. 소프트웨어 개발에서도 동일하게 적용할 수 있는데, 최종 코드는 사용자 도메인을 바라보는 관점에서 반영하면 된다. 즉, 애플리케이션이 도메인 모델을 기반으로 설계되어야 한다는 것을 의미한다.
객체지향은 이런 요구사항을 가장 범용적으로 만족시킬 수 있는 거의 유일한 모델링 패러다임이다.
객체지향을 사용했을 때
사용자들이 이해하고 있는 도메인 구조와 최대한 유사하게 코드를 구조화할 수 있다.
사용자의 관점, 설계자의 관점, 코드의 모습을 모두 유사한 형태로 유지할 수 있다.
표현적 차이
다시 한 번 강조하지만 소프트웨어 객체는 현실 객체에 대한 추상화가 아니다. 소프트웨어 객체와 현실 객체 사이의 관계를 가장 효과적으로 표현할 수 있는 단어는 바로 은유다.
즉, 소프트웨어 객체는 현실 객체를 모방한 것이 아닌 은유를 기반으로 재창조한 것이며, 현실 객체가 갖지 못한 특성을 가질 수도 있고 현실 객체가 하지 못하는 행동을 할 수도 있다!
그렇다면 은유를 통해 투영해야 하는 대상은 무엇일까? 바로 사용자가 도메인에 대해 생각하는 개념, 우리가 은유해야 하는 대상은 바로 도메인 모델이다.
표현적 차이가 중요한 이유는 소프트웨어를 이해하고 수정하기 쉽게 만들어주기 때문이다. 코드의 구조가 도메인의 구조를 반영하기 때문에 도메인을 이해하면 코드를 이해하기 훨씬 수월해진다.
불안정한 기능을 담는 안정적인 도메인 모델
도메인 모델을 기반으로 코드를 작성하는 두 번째 이유는 도메인 모델이 제공하는 구조가 상대적으로 안정적이기 때문이다.
사용자가 도메인을 바라보는 관점을 반영해 소프트웨어를 설계하고 구현함으로써 도메인의 '본질적인' 측면을 가장 잘 이해하고 있는 사용자의 관점을 반영할 수 있다.
안정적인 구조를 제공하는 도메인 모델을 기반으로 소프트웨어 구조를 설계하면 변경에 유연하게 대응할 수 있는 탄력적인 소프트웨어를 만들 수 있다. 도메인 모델은 기능을 구현할 때 참조할 수 있는 궁극적인 지도다.
불안정한 재료: 기능
유스케이스
기능적 요구사항이란 시스템이 사용자에게 제공해야 하는 기능의 목록을 정리한 것이다.
시스템이 사용자에게 기능을 제공하는 이유는 무엇인가? 사용자들은 시스템을 통해 얻고자하는 '목표'가 존재한다. 따라서 훌륭한 기능적 요구사항을 얻기 위해서 '목표를 가진 사용자'와 사용자의 목표를 만족시키기 위해 일련의 절차를 수행하는 '시스템 간의 상호작용' 관점에서 시스템을 바라봐야 한다.
이처럼 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스라 한다.
유스케이스의 가치
사용자들의 목표를 중심으로 시스템의 기능적인 요구사항을 이야기 형식으로 묶을 수 있다.
흩어져 있는 기능에 사용자 목표라는 문맥을 제공함으로써 각 기능이 유기적인 관계를 지닌 체계를 이룰 수 있다.
요구사항을 기억하고 관리하는 데 필요한 정신적 과부하를 줄인다.
example
유스케이스의 특성
1. 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 '텍스트'다.
유스케이스는 다이어그램이 아니다.
중요한 것은 상호작용의 흐름(이야기)이다.
사용자와 시스템 간의 상호작용을 일련의 이야기 흐름으로 표현하는게 중요한 것
다이어그램에 노력을 쏟지 말자.
2. 유스케이스는 하나의 시나리오가 아니라 여러 시나리오들의 집합이다.
시나리오(scenario)는 유스케이스를 통해 시스템을 사용하는 하나의 특정한 이야기 또는 경로다.
유스케이스는 하나의 시나리오가 아니라 사용자의 목표와 관련된 시나리오의 집합이다.
시나리오를 유스케이스의 인스턴스(use case instance) 라고도 한다.
3. 유스케이스는 단순한 피처(feature) 목록과 다르다.
피처는 시스템이 수행해야하는 기능의 목록을 단순하게 나열한 것이다.
유스케이스로 여러 피처를 묶고 사용자와의 상호작용 흐름 속에서 피처를 포함하는 이야기를 제공한다.
시스템의 기능에 대해 의사소통할 수 있는 문맥을 얻을 수 있다.
4. 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.
유스케이스는 자주 변경되는 사용자 인터페이스 요소는 배제한다.
사용자 관점에서 시스템의 행위에 초점을 맞춘다.
사용자 인터페이스를 배제한 유스케이스 형식을 본질적인 유스케이스(essential use case) 라고 한다.
5. 유스케이스는 내부 설계와 관련된 정보를 포함하지 않는다.
유스케이스의 목적은 연관된 시스템의 기능을 이야기 형식으로 모으는 것이지 내부 설계를 설명하는 것이 아니다.
유스케이스에서 객체 설계로의 전환은 경험과 상식과 의사소통을 기반으로 한 창조 작업이다.
유스케이스는 설계 기법도, 객체지향 기법도 아니다.
유스케이스가 단지 사용자가 바라보는 시스템의 외부 관점만을 표현한다는 점에 주목하자.
유스케이스는 시스템이 외부에 제공해야 하는 행위만 포함하기 때문에 시스템의 내부 구조를 유추할 수 있는 방법은 존재하지 않는다. 단지 기능적 요구사항을 사용자의 목표라는 문맥을 중심으로 묶기 위한 정리 기법일 뿐이다.
유스케이스를 객체로 변환하는 작업은 순수하게 창조적이고 예술적인 작업이다. 유스케이스를 기반으로 객체의 구조를 쉽게 추출할 수 있다는 것은 어설픈 설명이다. 객체의 구조나 책임에 대한 어떤 정보도 유스케이스에는 포함되지 않는다.
재료 합치기: 기능과 구조의 통합
도메인 모델, 유스케이스, 그리고 책임-주도 설계
불안정한 기능을 안정적인 구조 안에 담음으로써 변경에 대한 파급효과를 최소화하는 것은 훌륭한 객체지향 설계자가 갖춰야 할 기본적인 설계 능력이다.
도메인 모델은 안정적인 구조를 개념화하기 위해, 유스케이스는 불안정한 기능을 서술하기 위해 가장 일반적으로 사용되는 도구다. 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야 한다.
객체지향 패러다임은 모든 것이 객체라는 사상에서 출발한다.
따라서 유스케이스에 명시된 기능을 구현하는 프로그래머는 시스템을 사용자로부터 전송된 메시지를 수행하기 위해 책임을 수행하는 거대한 자율적인 객체로 본다.
시스템이라는 객체 안에는 더 작은 규모의 객체가 포함될 수 있다. 시스템이 수행해야 하는 커다란 규모의 책임은 시스템 안에 살아가는 더 작은 크기의 객체들의 협력을 통해 구현될 수 있는 것이다.
책임-주도 설계는 이 지점부터 적용된다.
시스템이 사용자에게 제공할 기능이 있다는 가정하에 객체들 간의 협력을 설계했지만, 사실 협력의 출발을 장식하는 첫 번쨰 메시지는 시스템의 기능을 시스템의 책임으로 바꾼 후 얻어지는 것이다.
시스템의 기능을 완성시키는 순서
우리는 도메인 모델에 포함된 개념을 은유하는 소프트웨어 객체를 선택해야 한다.
소프트웨어와 코드 사이의 표현적 차이를 줄이는 첫걸음이 된다.
협력을 완성하는 데 필요한 메시지를 식별하면서 객체들에게 책임을 할당해 나간다.
협력에 참여하는 객체를 구현하기 위해 클래스를 추가하고 속성과 함께 메시지를 구현한다.
객체 설계는 가끔 다음과 같이 표현되기도 한다.
요구사항들을 식별하고 도메인 모델을 생성한 후, 소프트웨어 클래스에 메서드를 추가하고, 요구사항을 충족시키기 위해 객체들 간의 메시지 전송을 정의하라.
견고한 객체지향 애플리케이션을 개발하기 위해서는 사용자 관점에서 시스템의 기능을 명시하고, 사용자와 설계자가 공유하는 안정적인 구조를 기반으로 기능을 책임으로 변환하는 체계적일 절차를 따라야 한다.
유스케이스에서 출발해 객체들의 협력으로 이어지는 일련의 흐름은 객체 안에 다른 객체로 포함되는 재귀적 합성이라는 객체지향의 기본 개념을 잘 보여준다.
기능 변경을 흡수하는 안정적인 구조
도메인 모델을 기반으로 객체 구조를 설계하는 이유는 도메인 모델이 안정적이기 때문이다.
도메인 모델을 구성하는 개념은 비즈니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다.
도메인 모델을 구성하는 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 유지된다.
기능적인 요구사항이 변경될 경우 책임과 객체 간의 대응 관계만 수정된다. 즉, 변경에 대한 파급효과를 최소호화하고 요구사항을 변경에 유연하게 대응할 수 있는 시스템을 구축할 수 있게 한다.
연결완전성
도메인을 모델링하기 위한 기법과 도메인을 프로그래밍하기 위해 사용하는 기법이 객체지향과 동일하다.
도메인 모델링에서 사용한 객체와 개념을 프로그래밍 설계에서의 객체와 클래스로 매끄럽게 변환할 수 있다.
가역성(reversibility)
코드의 변경으로부터 도메인 모델의 변경 사항을 유추할 수 있다.
연결완정성의 역방향 역시 성립한다는 것
객체지향에서는 도메인 모델과 코드 모두 동일한 모델링 패러다임을 공유하기 때문에 코드의 수정은 곧 모델의 수정이다.
도메인 모델은 사람들의 머릿속에 들어있는 공유된 멘탈 모델이다. 따라서 별도의 문서나 다이어그램을 가지고 있지 않더라도 유사한 모델이 공유될 수 있다면 그것으로 충분하다.
안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하자.
도메인 모델과 코드를 밀접하게 연관시키기 위해 노력하자.
그것이 유지보수하기 쉽고 유연한 객체지향 시스템을 만드는 첫 걸음이 될 것이다.
Last updated
Was this helpful?