🤓 객체지향의 사실과 오해 를 통해서 공부중입니다.
좋은 설계는 나중이라도 변경할 수 있는 여지를 남겨 놓는 설계다. 설계를 하는 목적은 나중에 설계하는 것을 허용하며, 설계의 일차적인 목표는 변경에 소요되는 비용을 낮추는 것이다.
객체지향 접근 방법은 자주 변경되지 않는 안정적인 객체 구조를 바탕으로 시스템 기능을 객체간의 책임으로 분배한다. 객체지향은 객체의 구조에 집중하고 기능이 객체의 구조를 따르게 만든다. 안정적인 객체 구존ㄴ 변경을 수용할 수 있는 유연한 소프트웨어를 만들 수 있는 기반을 제공한다.
객체지향 세계를 구축하기 위해서는 사용자에게 제공할 기능과 기능을 담을 안정적인 구조라는 재료가 준비돼 있어야 한다.
구조는 사용자나 이해관계자들이 도메인에 관해 생각하는 개념과 개념들 간의 관계로 표현하며, 기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위료 표현한다.
소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정 분야의 문제를 해결하기 위해 소프트웨어를 사용하는데, 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.
도메인 모델은 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다. 도메인 모델은 소프트웨어가 목적하는 영역 내의 개념과 개념 간의 관계, 다양한 규칙이나 제약 등을 추상화한 것이다.
최종 코드는 사용자가 도메인을 바라보는 관점을 반영해야 한다. 즉, 애플리케이션은 도메인 모델을 기반으로 설계되어야 한다. 도메인 모델은 사용자들이 도메인을 바라보는 관점이면서 설계자가 시스템의 구조를 바라보는 관점인 동시에 소프트웨어 안에 구현된 코드의 모습 그 자체이기 때문이다.
객체지향 패러다임은 사용자의 관점, 설계자의 관점, 코드의 모습을 모두 유사한 형태로 유지할 수 있게 하는 유용한 사고 도구와 프로그래밍 기법을 제공한다.
객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지가 모두 유산 모습을 유지하도록 만드는 것이 가능하며, 이러한 객체지향의 특징을 연결완전성 또는 표현적 차이라고 한다.
소프트웨어 객체는 현실 객체를 모방한 것이 아니라 은유를 기반으로 재창조한 것이다. 따라서 소프트웨어 객체는 현실 객체가 갖지 못한 특성을 가질 수도 있고 현실 객체가 하지 못하는 행동을 할 수도 있다. 이처럼 소프트웨어 객체와 현실 객체 사이의 의미적 거리를 가리켜 표현적 차이 또는 의미적 차이라고 한다.
소프트웨어 객체를 창조하기 위해 은유해야 하는 대상은 도메인 모델이다. 소프트웨어 객체는 그 대상이 현실적인지, 현실적이지 않은지에 상관없이 도메인 모델을 통해 표현되는 도메인 객체들을 은유해야 한다. 도메인 모델을 기반으로 설계하고 구현하는 것은 사용자가 도메인들 바라보는 관점을 코드에 그대로 반영할 수 있게 한다. 결과적으로 표현적 차이는 줄어들 것이며, 사용자의 멘탈 모델이 그대로 코드에 스며든다.
도메인 모델이 제공하는 구조는 상대적으로 안정적이다. 도메인 모델의 핵심은 사용자가 도메인을 바라보는 관점을 반영해 소프투에어를 설계하고 구현하는 것이다. 도메인에 대한 사용자의 관점을 반영해야 하는 이유는 사용자들이 누구보다도 도메인의 본질적인 측면을 가장 잘 이해하고 있기 때문이다. 사용자 모델에 포함된 개념과 규칙은 비교적 변경될 학률이 적기 때문에 사용자 모델을 기반으로 설계와 코드를 만들면 변경에 쉽게 대처할 수 있다.
사용자는 자신의 목표를 달성하기 위해 시스템과 상호작용한다. 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스라고 한다. 유스케이스의 가치는 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다.
유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 텍스트이며, 핵심은 그 상호작용을 일련의 이야기 흐름으로 표현하는 것이다.
유스케이스는 하나의 시나리오가 아니라 사용자의 목표와 관련된 모든 시나리오들의 집합이다. 이자 계산 유스케이스에서 첫 번째 시나리오는 예금주가 계좌를 선택하고 당일까지의 이자액을 계산하는 것이고, 두 번째 시나리오는 예금주가 계좌를 선택하고 특정 일자까지의 이자액을 계산하는 것이다. 두 번째 시나리오는 첫 번째 시나리오의 대안적인 흐름으로, 예금주는 당일까지의 이자액을 계산하거나 특정 일자까지의 이자액을 계산할 수 있다.
유스케이스는 단순한 피처 목록과 다르다. 예금 유스케이스에서 피처는 '시스템은 정기예금 정보를 보여준다.'와 '시스템은 당일이나 현재 일자의 이자를 계산한다.'이다. 피처의 단점은 두 피처를 서로 연관없는 독립적인 기능으로 보이게끔 만든다는 것이다. 두 피처를 '중도 해지 이자액을 계산한다'라는 유스케이스로 묶고 사용자와의 상호작용 흐름 속에서 두 피처를 포함하는 이야기를 제공함으로써 시스템의 기능에 대해 의사소통할 수 있는 문맥을 얻을 수 있다.
유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다. 유스케이스는 자주 변경되는 사용자 인터페이스 요소는 배제하고 사용자 관점에서 시스템의 행위에 초점을 맞춘다. 이처럼 사용자 인터페이스를 배제한 유스케이스 형식을 본질적인 유스케이스라고 한다.
유스케이스는 내부 설계와 관련된 정보를 포함하지 않는다. 유스케이스의 목적은 연관된 시스템의 기능을 이야기 형식으로 모으는 것이다.
유스케이스는 단지 사용자가 바라보는 시스템의 외부 관점만을 표현한다. 유스케이스는 시스템의 내부 구조나 실행 메커니즘에 관한 어떤 정보도 제공하지 않는다. 유스케이스에는 단지 사용자가 시스템을 통해 무엇을 얻을 수 있고 어떻게 상호작용할 수 있느냐에 관한 정보만 기술된다.
유스케이스 텍스트 안에서 도메인 모델에서 사용할 용어에 대한 힌트를 얻을 수도 있다. 유스케이스 안에 포함된 이야기 흐름 속에서 나타나는 계좌, 이자, 금액과 같은 단어들은 도메인 모델에 포함될 수 있는 개념이나 속성에 관한 정보를 제공한다. 그러나 유스케이스 안에는 영감을 불러일으킬 수 있는 약간의 힌트만 들어있을 뿐, 도메인 모델을 구축할 수 있는 모든 정보가 포함되어 있지는 않다.
불안정한 기능을 안정적인 구조 안에 담음으로써 변경에 대한 파급효과를 최소화하는 것은 훌륭한 객체지향 설계자가 갖춰야 할 기본적인 설계 능력이다. 도메인 모델은 안정적인 구조를 개념화하기 위해, 유스케이스는 불안정한 기능을 서술하기 위해 가장 일반적으로 사용되는 도구다.
도메인 모델은 구조를, 유스케이스는 협력의 출발점인 시스템 책임을 제공한다. 책임 주도 설계 방법은 시스템의 기능을 역할과 책임을 수행하는 객체들의 협력 관계를 바라보게 함으로써 도메인 모데로가 유스케이스를 통합한다.
정기 예금을 중도 해지할 경우 지급 받을 수 있는 이자액을 계산하는 기능을 구현하려면 유스케이스에 명시된 시스템의 행위를 객체의 책임으로 분배해야 한다. 프로그래머는 기능이라는 단어를 책임이라는 단어로 대체하고, 시스템이 '중도 해지 이자액을 계산하라'라는 메시지를 받는 객체라고 가정한다.
시스템에 할당된 책임은 시스템 안에서 실행될 소프트웨어 객체들의 협력으로 구현되어야 한다. 메시지를 받을 객체를 선택하고, 그 객체가 다른 객체에 전송할 메시지를 식별한 후, 다시 그 메시지를 받을 객체를 선택함으로써 자율적인 객체들의 협력 관계를 창조한다. 이 때 할당 받을 객체들은 안정적인 도메인 모델을 기반으로 해야 한다.
도메인 모델을 기반으로 객체 구조를 설계하는 이유는 도메인 모델이 안정적이기 때문이다. 도메인 모델을 구성하는 개념은 비즈니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다. 또한 도메인 모델을 구성하는 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다.
도메인 모델과 코드 모두 동일한 모델링 패러다임을 공유하기 떄문에 코드의 수정이 곧 모델의 수정이 된다. 이처럼 모델에서 코드로의 매끄러운 흐름을 의미하는 연결완정성과 반대로 코드에서 매끄러운 흐름을 의미하는 것을 가역성이라고 한다.
안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하고, 도메인 모델과 코드를 밀접하게 연관시키기위해 노력하는 것이 유지보수하기 쉽고 유연한 객체지향 시스템을 만드는 첫걸음이 된다.