Chapter6 객체 지도

  • 자율적인 객체들로 시스템을 분할하는 객체지향이 강력한 이유는 사람들이 실세계의 현상을 인지하고 이해하는 관점을 그대로 소프트웨어에 투영할 수 있기 때문이다.

  • 자주 변경되는 기능이 아니라 안정적인 구조를 따라 역할, 책임, 협력을 구성하라.


1. 기능 설계 대 구조 설계

  • 소프트웨어 제품 설계의 두 가지 측면

    1. 기능(function): 기능 측면의 설계는 제폼이 사용자를 위해 무엇을 할 수 있는지에 초점을 맞춘다.

    2. 구조(structure): 구조 측면의 설계는 제품의 형태가 어떠해야 하는지에 초점을 맞춘다.

  • 소프트웨어를 개발하는 일차적인 이유는 사용자에게 훌륭한 기능을 제공하기 위해서다.

  • 소프트웨어를 개발하는 초기 단계에서는 사용자가 무엇을 원하는지, 그리고 사용자가 원하는 것을 만족시키기 위해 시스템이 어떤 기능을 제공해야 하는지에 초점을 맞춰야 한다.

  • 성공적인 소프트웨어들이 지닌 공통적인 특징은 훌륭한 기능을 제공하는 동시에 사용자가 원하는 새로운 기능을 빠르고 안정적으로 추가할 수 있다는 것이다.

  • 소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다.

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

  • 좋은 설계는 나중에라도 변경할 수 있는 여지를 남겨 놓은 설계다.

  • 변경에 대비하고 변경의 여지를 남겨 놓는 가장 좋은 방법은 자주 변경되는 기능이 아닌 안정적인 구조를 중심으로 설계하는 것이다.


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

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

  • 기능은 사용자가 자신의 목표를 달성하기 위해 사용할 수 있는 시스템의 서비스다.

  • 구조는 시스템의 기능을 구현하기 위한 기반으로, 기능 변경을 수용할 수 있도록 안정적이어야 한다.


3. 안정적인 재료: 구조

도메인 모델

  • 소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정한 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.

  • 모델은 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다. 즉, 대상을 추상화하고 단순화한 것이다.

  • 도메인 모델이란 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다.

  • 도메인 모델은 이해관계자들이 바라보는 멘탈 모델이다.

  • 멘탈 모델이란 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다.

  • 사용자들은 자신의 멘탈 모델과 유사한 방식으로 제품이 반응하고 움직일 것이라고 기대하기 때문에 훌륭한 디자인이란 사용자가 예상하는 방식에 따라 정확하게 반응하는 제품을 만드는 것이다.

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

  • 도메인 모델이란 사용자들이 도메인을 바라보는 관점이며, 설계자가 시스템의 구조를 바라보는 관점인 동시에 소프트웨어 안에 구현된 코드의 모습 그 자체이다.

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

표현적 차이

  • 소프트웨어 객체와 현실 객체 사이의 의미적 거리를 표현적 차이 또는 의미적 차이라고 한다. 핵심은 은유를 통해 현실 객체와 소프트웨어 객체 사이의 차이를 최대한 줄이는 것이다.

  • 소프트웨어 객체를 창조하기 위해 우리가 은유해야 하는 대상은 바로 도메인 모델이다.

  • 소프트웨어 객체는 그 대상이 현실적인지, 현실적이지 않은지에 상관없이 도메인 모델을 통해 표현되는 도메인 객체들을 은유해야 한다.

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

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

  • 도메인 모델의 핵심은 사용자가 도메인을 바라보는 관점을 반영해 소프트웨어를 설계하고 구현하는 것이다.

  • 도메인에 대한 사용자의 관점을 반영해야 하는 이유는 사용자들이 누구보다도 도메인의 '본질적인' 측면을 가장 잘 이해하고 있기 때문이다.

  • 본질적이라는 것은 변경이 적고 비교적 그 특성이 오랜 시간 유지된다는 것을 의미한다.

  • 안정적인 구조를 제공하는 도메인 모델을 기반으로 소프트웨어의 구조를 설계하면 변경에 유연하게 대응할 수 있는 탄력적인 소프트웨어를 만들 수 있다.


4. 불안정한 재료: 기능

유스케이스

  • 기능적 요구사항이란 시스템이 사용자에게 제공해야 하는 기능의 목록을 정리한 것이다.

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

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

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

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

유스케이스의 특성

  1. 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 '텍스트'다.

    • 유스케이스의 핵심은 사용자와 시스템 간의 상호작용을 일련의 이야기 흐름으로 표현하는 것이다.

    • 중요한 것은 유스케이스에 담겨있는 이야기다.

  2. 유스케이스는 하나의 시나리오가 아니라 여러 시나리오들의 집합이다.

    • 시나리오는 유스케이스를 통해 시스템을 사용하는 하나의 특정한 이야기 도는 경로다.

    • 시나리오를 유스케이스 인스턴스라고도 한다.

  3. 유스케이스는 단순한 피처(feature) 목록과 다르다.

    • 피처는 시스템이 수행해야 하는 기능의 목록을 단순하게 나열한 것이다.

    • 유스케이스의 강점은 유스케이스가 단순히 기능을 나열하는 것이 아니라 이야기를 통해 연관된 기능들을 함께 묶을 수 있다는 점이다.

  4. 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.

    • 사용자 인터페이스를 배제한 유스케이스 형식을 본질적인 유스케이스(essential use case)라고 한다.

  5. 유스케이스는 내부 설계와 관련된 정보를 포함하지 않는다.

    • 유스케이스에서 객체 설계로의 전환은 공학적인 규칙과 원칙을 기반으로 한 변환 작업이 아니라 경험과 상식과 의삿통을 기반으로 한 창조 작업이다.

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

  • 유스케이스는 시스템의 내부 구조나 실행 메커니즘에 관한 어떤 정보도 제공하지 않는다.

  • 유스케이스에는 단지 사용자가 시스템을 통해 무엇을 얻을 수 있고 어떻게 상호작용할 수 있느냐에 관한 정보만 기술한다.

  • 사실 유스케이스는 객체지향과도 상관이 없다.

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

  • 유스케이스를 기반으로 객체의 구조를 쉽게 추출할 수 있다는 어설픈 설명에 속지 마라. 유스케이스는 객체의 구조나 책임에 대한 어떤 정보도 제공하지 않는다.

  • 유스케이스 안에는 영감을 불러일으킬 수 있는 약간의 힌트만 들어 있을 뿐이다.


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

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

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

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

  • 요구사항들을 식별하고 도메인 모델을 생성한 후, 소프트웨어 클래스에 메서드들을 추가하고, 요구사항을 충족시키기 위해 객체들 간의 메시지 전송을 정의하라.

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

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

  • 책임-주도 설계는 유스케이스로부터 첫 번째 메시지와 사용자가 달성하려는 목표를, 도메인 모델로부터 기능을 수용할 수 있는 안정적인 구조를 제공받아 실제로 동작하는 객체들의 협력 공동체를 창조한다.

  • 책임-주도 설계 방법은 시스템의 기능을 역할과 책임을 수행하는 객체들의 협력 관계로 바라보게 함으로써 두 가지 기본 재료인 유스케이스와 도메인 모델을 통합한다.

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

  • 객체의 이름은 도메인 모델에 포함된 개념으로부터 차용하고, 책임은 도메인 모델에 정의한 개념의 정의에 부합하도록 할당한다.

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

  • 도메인 모델을 기반으로 객체 구조를 설계하는 이유는 도메인 모델이 안정적이기 때문이다.

  • 도메인 모델이 안정적인 이유

    1. 도메인 모델을 구성하는 개념은 비즈니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다.

    2. 도메인 모델을 구성하는 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다.

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

  • 도메인 모델은 문서나 다이어그램이 아니다. 도메인 모델은 사람들의 머릿속에 들어있는 공유된 멘탈 모델이다.

  • 사람들이 동일한 용어와 동일한 개념을 이용해 의사소통하고 코드로부터 도메인 모데을 유추할 수 있게 하는 것이 도메인 모델의 진정한 목표다.

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


6. Conclusion

책임-주도 설계를 하기 전 단계에 대한 파트라고 생각한다. 도메인 모델과 유스케이스에 대한 설명이 이번 파트의 주제이고 이를 활용하여 책임-주도 설계를 해야한다고 한다. 물론 도메인 모델과 유스케이스가 책임-주도 설계를 위해 존재하는 것은 아니지만 유지보수가 쉽고 안정적인 소프트웨어를 만들기 위해서는 참고할 수 있는 유용한 기술이라고 생각한다. 책임-주도 설계보다 앞에서 설계해야 하지만 해당 파트가 뒤로 밀린 이유는 그래도 객체지향과 더욱 밀접한 책임-주도 설계가 더 중요해서가 아닐까 싶다. 도메인... 우테코 프리코스를 하면서 들어본 개념이다. 이번 파트를 읽어보면서 도메인 모델에 대해서는 정도 감이 잡히지만 내가 실제로 소프트웨어를 설계한다면 어떻게 도메인 모델을 나눌지에 대해서는 아직 감이 잡히지 않는다. 틀리더라도 실제로 적용하여 내 것으로 만들어 보고 싶다는 생각이 든다. 그리고 Happy new year!


📅 2023-01-01

Last updated