06 객체 지도

Byung Seon Kang·2022년 7월 18일

유일하게 변하지 않는 것은 모든 것이 변한다는 사실 뿐이다.
-Heraclitus of Ephesus

  • 여행중 길을 찾는 방법은 두 가지 방법이 있다.
    1) 다른 사람에게 길을 묻는 방법(functional,solution-directed approach)
    2) 지도를 이용해 길을 이용하는 방법(structural, problem-directed approach)

  • 길을 묻는 방법은 현재의 요구만을 만족시킬 수 있다.
    하지만 지도는 현재의 목적뿐만 아니라 다양한 목적을 위해 재사용될 수 있다. 즉, 범용적.

  • 지도가 범용적인 이유는 지도를 사용하려는 사람들이 원하는 '기능'에 비해 지도에 표시된 '구조'가 더 안정적이기 때문이다.

  • 지도 은유의 핵심은 기능이 아니라 구조를 기반으로 모델을 구축하는 편이 좀 더 범용적이고 이해하기 쉬우며 변경에 안정적이라는 것이다.

  • 사람들의 요구사항은 계속 변하기 때문에 모델이 제공해야 하는 기능 역시 이에 따라 지속적으로 변할 수밖에 없다. 따라서 기능을 중심으로 구조를 종속시키는 접근법은 범용적이지 않고 재사용이 불가능하며 변경에 취약한 모델을 낳게 됨.

  • 이와 달리 안정적인 구조를 중심으로 기능을 종속시키는 접근법은 범용적이고 재사용 가능하며 변경에 유연하게 대처할 수 있는 모델을 만든다.

  • 이번 장에서는 기능이 아니라 구조를 바탕으로 시스템을 분할하는 객체지향의 또 다른 측면에 관해 설명할 것.


1. 기능 설계 대 구조 설계

  • 모든 소프트웨어 제품의 설계에는 두 가지 측면이 존재. 하나는 '기능(function)' 측면의 설계, 다른 하나는 '구조(structure)' 측면의 설계.

  • 기능 측면의 설계는 제품이 사용자를 위해 무엇을 할 수 있는지에 초점을 둔다.
    구조 측면의 설계는 제품의 형태가 어떠해야 하는지에 초점을 맞춘다.

  • 설계의 가장 큰 도전은 기능과 구조라는 두 가지 측면을 함께 녹여 조화를 이루도록 만드는 것.

  • 소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다.
    결국 설계라는 행위를 중요하게 만드는 것은 변경에 대한 필요성이다.
    미래를 예측할 수 없기에 미래를 대비하는, 즉 변경을 수용할 수 있는 선택의 여지를 설계에 마련해놔야 한다는 이미.

  • 전통적인 기능 분해(functional decomposition)는 자주 변경되는 기능을 중심으로 설계한 후 구조가 기능에 따르게 한다.
    이러면 시스템 기능은 더 작은 기능으로 분해되고 각 기능은 서로 밀접하게 관련된 하나의 덩어리를 이루기 때문에 기능이 변경될 경우 설게된 소프트웨어가 전체적으로 요동치게 된다.

  • 반면 객체지향 접근방법은 자주 변경되지 않는 안정적인 객체 구조를 바탕으로 시스템의 기능을 객체 간의 책임으로 분배한다.
    시스템 기능은 더 작은 책임으로 분할되고 적절한 객체에게 분배되므로 기능이 변경되어도 객체 간의 구조는 그대로 유지된다.

2. 두 가지 재료:기능과 구조

  • 객체지향 세계를 구축하기 위해서는 사용자에게 제공할 '기능'과 기능을 담을 안정적인 '구조'라는 재료가 준비되어 있어야 함.

  • 기능은 자신의 목표를 달성하기 위해 사용할 수 있는 시스템의 서비스.
    구조는 시스템의 기능을 구현하기 위한 기반. 기능 변경을 수용할 수 있도록 안정적이어야 한다.

  • 초점은 두 재료를 어디에서 구하느냐

    구조는 사용자나 이해 관계자들이 domain에 관해 생각하는 개념과 개념들간의 관계로 표현
    기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 서비스

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

3. 안정적인 재료: 구조

도메인 모델

  • 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다 - Evans
    ex) 무료한 시간을 달래기 위해 게임 소프트웨어를 사용한다.

  • 도메인 모델에서 모델이란 대상을 단순화해서 표현한 것.
    모델은 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다.
    복잡성을 관리하기 위해 사용하는 기본적인 도구.

  • 두 개념을 연결해보면 도메인 모델이란 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태이다.
    도메인 모델은 소프트웨어 개발과 관련된 이해관계자들이 도메인에 대해 생각하는 관점이 된다.
    ex) 은행 업무 종사자 - 은행 도메인 = 고객과 계좌 사이의 돈의 흐름.
    중고 자동차 판매상 - 구매되는 자동차와 판매되는 자동차의 교환으로 자동차 도메인을 바라봄.

  • 도메인 모델은 단순히 다이어그램이 아니다. 이해관계자들이 바라보는 Mental Model이다.
    *멘탈 모델 : 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형.
    제품에 관한 모든 것이 사용자들이 제품에 대해 가지고 있는 멘탈 모델과 정확하게 일치해야 한다 - Norman

  • 사용자 모델 : 사용자가 제품에 대해 가지고 있는 개념들의 모습

  • 디자인 모델 : 설계자가 마음 속에 갖고 있는 시스템에 대한 개념화

  • 시스템 이미지 : 최종 제품.
    설계자는 디자인 모델을 기반으로 만든 시스템 이미지가 사용자 모델을 정확하게 반영하도록 노력해야 한다.

    도메인 모델은 소프트웨어에 대한 멘탈 모델이다.

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

  • 최종 코드는 사용자가 도메인을 바라보는 관점을 반영해야 한다.
    이는 곧 애플리케이션이 도메인 모델을 기반으로 설계되어야 함을 의미.
    도메인 모델은 사용자들이 도메인을 바라보는 관점이며, 설계자가 시스템의 구조를 바라보는 관점인 동시에 소프트웨어 안에 구현된 코드의 모습 그 자체이기 때문.
  • 결과적으로 객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지 모두가 유사한 모습을 유지하도록 만드는 것이 가능해짐.
    이를 연결완전성 또는 표현적 차이라고 한다.

표현적 차이

  • 소프트웨어 객체와 현실 객체 사이의 관계를 가장 효과적으로 표현하는 단어는 은유.
    모방이 아님.
    따라서 소프트웨어 객체는 현실 객체가 갖지 못한 특성을 가질 수도 있고 현실 객체가 하지 못하는 행동을 할 수도 있다.

  • 이런 의미적 거리를 가리켜 표현적 차이 또는 의미적 차이라고 표현.
    핵심은 은유를 통해 이 차이를 최대한 줄이는 것.

  • 하지만 가상의 세계를 창조하는 직업(게임에서의 마법, 괴물등)은 현실 객체를 은유할 수 없음.
    결국 우리가 은유를 통해 투영해야할 대상은 사용자가 도메인에 대해 생각하는 개념들.
    우리는 도메인 객체들을 은유해야 한다.

  • 표현적 차이를 줄이는 것이 중요한 이유는 소프트웨어를 이해하고 수정하기 쉽게 만들어주기 때문이다.

불안정한 기능을 담는 안정적인 도메인 모델

  • 도메인 모델을 기반으로 코드를 작성하는 두 번째 이유는 도메인 모델이 제공하는 구조가 상대적으로 안정적이기 때문이다.
    사용자 모델에 포함된 개념과 규칙은 비교적 변경될 확률이 적기 때문에 사용자 모델을 기반으로 설계와 코드를 만들면 변경에 쉽게 대처할 수 있을 가능성이 커진다.

4. 불안정한 재료: 기능

유스케이스

  • 기능적 요구사항은 시스템이 사용자에게 제공해야 하는 기능의 목록을 정리한 것.
    이를 얻기 위해서는 목표를 가진 사용자와 사용자의 목표를 만족시키기 위해 일련의 절차를 수행하는 시스템 간의 '상호작용' 관점에서 시스템을 바라봐야 한다.
    이 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스라고 한다.

    유스케이스는 시스템의 이해관계자들 간의 계약을 행위 중심으로 파악한다. 유스케이스는 이해관계자들 중에서 일차 액터라 불리는 행위자의 요청에 대한 시스템의 응답으로서, 다양한 조건 하에 있는 시스템의 행위를 서술한다. ... - Cockburn

  • 일차 액터(primary actor)란 시스템의 서비스 중에 하나를 요청하는 이해관계자로, 하나의 목표를 가지고 유스케이스를 시작하는 액터를 의미한다.

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

유스케이스의 특성

  • 첫째, 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 '텍스트'다. 다이어그램이 아니다.

이야기 흐름으로 상호작용을 표현하는 것이 핵심.

  • 둘째, 유스케이스는 하나의 시나리오가 아니라 여러 시나리오들의 집합이다.
    사용자의 목표와 관련된 모든 시나리오.
  • 셋째, 유스케이스는 단순한 feature 목록과 다르다.
    feature는 시스템이 수행해야하는 기능의 목록을 단순하게 나열한 것이라 서로 연관이 없는 독립적인 기능으로 보이게끔 만든다는 점임.
    유스케이스는 단순히 기능을 나열하지 않고 이야기를 통해 연관된 기능을 함께 묶어준다.
  • 넷째, 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.
    자주 변경되는 사용자 인터페이스 요소는 배제하고 사용자 관점에서 시스템의 행위에 초점을 맞춤. 이런 유스케이스 형식을 essential use case 라고 한다.
  • 다섯째, 유스케이스는 내부 설계와 관련된 정보를 포함하지 않음.
    시스템의 기능을 이야기 형식으로 모으는 것이지 내부 설계를 설명하는 것이 아님.

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

  • 유스케이스가 단지 사용자가 바라보는 시스템의 외부 관점만을 표현한다는 점에 주목.
    유스케이스는 시스템의 내부 구조나 실행 메커니즘에 관한 어떤 정보도 제공하지 않는다.

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

  • 더 알고싶으면 Structuring Use Cases with Goals - Cockburn를 읽어보라.

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

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

  • 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야 한다.

  • 유스케이스는 사용자에게 제공할 기능을 시스템의 책임으로 보게 함으로써 객체 간의 안정적인 구조에 책임을 분배할 수 있는 출발점을 제공.

  • 도메인 모델은 기능을 수용하기 위해 은유할 수 있는 안정적인 구조를 제공

  • 책임-주도 설계는 유스케이스로부터 첫 번째 메시지와 사용자가 달성하려는 목표를, 도메인 모델로부터 기능을 수용할 수 있는 안정적인 구조를 제공받아 실제로 동작하는 객체들의 협력 공동체를 창조.
    -> 즉, 유스케이스와 도메인 모델을 통합.
    물론 책임-주도 설계를 위해 유스케이스와 도메인 모델이 꼭 필요한 것도 아니고, 유스케이스와 도메인 모델이 책임-주도 설계에서만 사용되는 것도 아니다.

    중요한 것은 견고한 객체지향 애플리케이션을 개발하기 위해서는 사용자의 관점에서 시스템의 기능을 명시하고, 사용자와 설계자가 공유하는 안정적인 구조를 기반으로 기능을 책임으로 변환하는 체계적인 절차를 따라야 한다는 것.

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

  • 도메인 모델을 기반으로 객체 구조를 설계하는 이유는 위에서 말했듯 도메인 모델이 안정적이기 때문.
  • 기능적인 요구사항이 변경될 경우 객체 간의 대응 관계만 수정될 뿐.
  • 도메인 모델은 사람들의 머릿속에 들어있는 공유된 멘탈 모델. 별도의 문서나 다이어그램이 없더라도 유사한 모델이 공유될 수 있다면 그것으로 충분하다.
  • 안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하라. 도메인 모델과 코드를 밀접하게 연관시키기 위해 노력해라.
profile
왜 필요한지 질문하기

0개의 댓글