본문 바로가기
도서/프로그래밍

[06] 객체지향의 사실과 오해 - 객체지도

by POWER_ESFJ 2023. 12. 31.

 

객체지도는 객체지향 프로그래밍에서 사용되는 개념입니다. 객체지향 프로그래밍은 객체들의 상호작용을 중심으로 프로그램을 구성하는 방법론입니다. 객체지도는 이러한 객체들의 관계와 상호작용을 시각적으로 표현한 도구입니다. 객체지도를 사용하면 프로그램의 구조를 쉽게 이해하고 관리할 수 있습니다.

 

유일하게 변하지 않는 것은 모든 것이 변한다는 사실뿐이다. -헤라클레이토스(Heraclitus of Ephesus)

 

지도는 길을 찾는 데 필요한 구체적인 기능이 아니라 길을 찾을 수 있는 ‘구조’를 제공한다.

지도는 범용적이다. (새로운 목적까지도 만족시킬 수 있다.)

객체지향은 지도와 같다. 자주 변경되는 기능이 아니라 안정적인 구조를 기반으로 시스템을 구조화한다.

기능 설계 대 구조 설계

모든 소프트웨어 제품의 설계에는 두 가지 측면이 존재한다.

하나는 ‘기능(function)’ 측면의 설계이고, 다른 하나는 ‘구조(structure)’ 측면의 설계다.

소프트웨어가 사용자에게 가치 있는 이유는 사용자가 필요로 하는 기능을 제공하기 때문이다.

훌륭한 기능이 훌륭한 소프트웨어를 만드는 충분조건이라고 한다면 훌륭한 구조는 훌륭한 소프트웨어를 만들기 위한 필요조건이다. 성공적인 소프트웨어들이 지닌 공통적인 특징은 훌륭한 기능을 제공하는 동시에 사용자가 원하는 새로운 기능을 빠르고 안정적으로 추가할 수 있다는 것이다.

요구사항이 변경되지 않는다면 개발자의 삶은 좀 더 단순하고 지루했을지도 모른다.

소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다. 설계라는 행위를 중요하게 만드는 것은 변경에 대한 필요성이다.

훌륭한 설계자는 사용자가 만족할 수 있는 훌륭한 기능을 제공하는 동시에 예측 불가능한 요구사항 변경에 유연하게 대처할 수 있는 안정적인 구조를 제공하는 능력을 갖춰야 한다.

미래에 대비하는 가장 좋은 방법은 변경을 예측하는 것이 아니라 변경을 수용할 수 있는 선택의 여지를 설계에 마련해 놓는 것이다. 설계의 일차적인 목표는 변경에 소요되는 비용을 낮추는 것이다.

전통적인 기능 분해(functional decomposition)는 자주 변경되는 기능을 중심으로 설계한 후 구조가 기능에 따르게 한다. 이것이 바로 전통적인 기능 분해 방법이 변경에 취약한 이유다. 각 기능은 서로 밀접하게 관련된 하나의 덩어리를 이루기 때문에 기능이 변경될 경우 기능의 축을 따라 설계된 소프트웨어가 전체적으로 요동치게 된다.

이에 비해 객체지향 접근방법은 자주 변경되지 않는 안정적인 객체 구조를 바탕으로 시스템 기능을 객체 간의 책임으로 분배한다. 객체지향 객체의 구조에 집중하고 기능이 객체의 구조를 따르게 만든다. 시스템 기능은 더 작은 책임으로 분할되고 적절한 객체에게 분배되기 때문에 기능이 변경되더라도 객체 간의 구조는 그대로 유지된다.

객체 지도는 빠르게 변화하는 기능을 수용할 수 있는 자리를 제공한다. 객체 지도는 안정적이며 재사용 가능하면서도 범용적이다. 사람들에게 길을 묻지 마라. 객체를 이용해 지도를 만들어라. 기능은 지도에 표시된 길을 따라 자연스럽게 흘러갈 것이다.

두 가지 재료: 기능과 구조

  • 구조는 사용자나 이해관계자들이 도메인(domain)에 관해 생각하는 개념과 개념들간의 관계로 표현한다.
  • 기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위로 표현한다.

일반적으로 기능을 수집하고 표현하기 위한 기법을 유스케이스 모델링이라고 하고 구조를 수집하고 표현하기 위한 기법을 도메인 모델링이라고 한다.

안정적인 재료: 구조

도메인 모델

사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.

도메인 모델에서 모델이란 대상을 단순화해서 표현한 것이다. (추상화)

은행 업무에서 도메인 모델이란 고객과 계좌 사이의 돈의 흐름이다.

도메인 모델은 단순히 다이어그램이 아니다. 도메인 모델은 이해관계자들이 바라보는 멘탈 모델(Mental Model)이다. 멘탈 모델이란 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다.

도메인의 모습을 담을 수 있는 객체지향

객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지 모두가 유사한 모습을 유지하도록 만드는 것이 가능하다. 객체지향의 이러한 특징을 연결완정성 또는 표현적 차이라고 한다.

표현적 차이

객체는 현실 객체에 대한 은유, 또는 사용자가 바라보는 멘탈 모델에 대한 은유.

사용자의 멘탈 모델과 프로그래밍 객체의 차이를 줄여야 한다.

도메인 모델은 도메인의 개념들이 코드에서 사용될 개념과 관계에 대한 구조를 제공한다.

사용자 모델에 포함된 개념과 규칙은 비교적 변경될 확률이 적기 떄문에 사용자 모델을 기반으로 설계와 코드를 만들면 변경에 쉽게 대처할 수 있을 가능성이 커진다.

불안정한 재료: 기능

유스케이스

사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스라고 한다.

 

유스케이스의 가치는 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다.

유스케이스의 특성

  1. 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 ‘텍스트’다. 유스케이스는 다이어그램이 아니다.
  2. 하나의 시나리오가 아니라 여러 시나리오의 집합이다
  3. 단순한 피처(feature) 목록과 다르다. 피처는 시스템이 수행해야 하는 기능의 목록을 단순하게 나열한 것이다. 이야기를 통해 연관된 기능들을 함께 묶는 것이다.
  4. 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다. 자주변경되는 사용자 인터페이스 요소는 배제하고 사용자 관점에서 시스템의 행위에 초점을 맞춘다.
  5. 내부 설계와 관련된 정보를 포함하지 않는다.

유스케이스는 설계 기법도, 객체지향 기법도 아니다

유스케이스는 객체지향과도 상관이 없다. 유스케이스는 단지 기능적 요구사항을 사용자의 목표라는 문맥을 중심으로 묶기 위한 정리 기법일 뿐이다.

 

유스케이스는 객체의 구조나 책임에 대한 어떤 정보도 제공하지 않는다.

물론 유스케이스 텍스트 안에서 도메인 모델에서 사용할 용어에 대한 힌트를 얻을 수도 있다. 그러나 유스케이스 안에 도메인 모델을 구추할 수 있는 모든 정보가 포함돼 있다는 착각에 빠지기 말기 바란다.

재료 합치기: 기능과 구조의 통합

도메인 모델, 유스케이스, 그리고 책임-주도 설계

불안정한 기능을 안정적인 구조 안에 담음으로써 변경에 대한 파급효과를 최소화하는 것은 훌륭한 객체지향 설계자가 갖춰야할 기본적인 설계 능력이다.

 

 

도메인 모델, 유스케이스 = 지도

시스템의 기능(유스케이스) ⇒ 책임으로 변경

책임을 수행할 객체 ⇒ 도메인 모델에 포함된 개념을 은유하는 소프트웨어 객체를 선택

소프트웨어와 코드 사이의 표현적 차이를 줄이는 첫 걸음

협력을 완성하는 데 필요한 메시지를 식별하면서 객체들에게 책임을 할당해 나간다.

마지막으로 협력에 참여하는 객체를 구현하기 위해 클래스를 추가하고 속성과 함께 메서드를 구현하면 시스템의 기능이 완성된 것이다.

 

사용자의 관점에서 시스템의 기능을 명시하고, 사용자와 설계자가 공유하는 안정적인 구조를 기반으로 기능을 책임으로 변환하는 체계적인 절차를 따라야 한다는 것이다.

기능 변경을 흡수하는 안정적인 구조

도메인 모델을 기반으로 객체 구조를 설계하는 이유

  • 도메인 모델을 구성하는 개념은 비지니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다.
  • 도메인 모델을 구성하는 개념 간의 관계는 비지니스 규칙을 기반으로 하기 때문에 비지니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다.

객체지향의 가장 큰 장점은 도메인을 모델링하기 위한 기법과 도메인을 프로그래밍하기 위해 사용하는 기법이 동일하다는 점이다. 따라서 도메인 모델링에서 사용한 객체와 개념을 프로그래밍 설계에서의 객체와 클래스로 매끄럽게 변환할 수 있다. 앞에서 객체지향의 이 같은 특성을 연결완정성이라고 설명했다.

 

객체지향이 강력한 이유는 연결완정성의 역방향 역시 성립한다는 것이다. 즉, 코드의 변경으로부터 도메인 모델의 변경사항을 유추할 수 있다. 모델에서 코드로의 매끄러운 흐름을 의미하는 연결완정성과 반대로 코드에서 모델로의 매끄러운 흐름을 의미하는 것을 가역성(reversibility)이라고 한다.

변경된 코드로부터 자연스럽게 개념적인 도메인 모델의 구조를 유추할 수 있다.

 

안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하라. 도메인 모델과 코드를 밀접하게 연관시키기 위해 노력하라. 그것이 유지보수하기 쉽고 유연한 객체지향 시스템을 만드는 첫걸음이 될 것이다.