Today I Learned

[도메인 주도 설계] 05. 소프트웨어에서 표현되는 모델 (1) 본문

도메인 주도 설계

[도메인 주도 설계] 05. 소프트웨어에서 표현되는 모델 (1)

하이라이터 2021. 11. 19. 02:03
728x90
  • 모델과 구현은 상세 수준에서 연결돼야 한다.
  • 객체 간의 연관관계를 설계하고, 연간 관계를 합리적으로 구성하는 문제를 논의하는 것으로 시작하자.
    • 객체 간의 연관관계를 이해하고 묘사하는 것은 간단하지만 실제로 구현하는 것은 힘든 문제일 수 있다.
    • 연관 관계를 토대로 상세한 구현 결정이 MODEL-DRIVEN DESIGN을 실현하는데 얼마나 중요한가를 알 수 있다.
  • 상세한 모델 선택과 구현 관심사 간의 관계는 모델을 표현하는 세 가지 패턴인 ENTITY, VALUE OBJECT, SERVICE를 구분하며 설명한다.
  • 마지막으로 MODULE에 관해 논의하면서 모든 설계 관련 의사결정은 도메인에 부여된 통찰력을 바탕으로 내려야한다는 것을 알게 될 것이다.

연관관계

  • 모델링과 실제 구현 간의 상호작용은 여러 객체 간의 연관관계에서 특히 까다롭다.
  • 현실세계에서는 수많은 다대다(many-to-many) 연관관계가 있으며, 그 중 상당수는 양방향으로 나타난다. 이러한 일반적인 연관관계는 구현과 유지보수를 복잡하게 만든다.
  • 연관 관계를 좀 더 쉽게 다루는 방법
    1. 탐색 방향을 부여한다
    2. 한정자(qualifier)를 추가해서 다중성(multiplicity)를 줄인다.
    3. 중요하지 않은 연관관계를 제거한다.
  • 요구사항에 두 방향을 모두 탐색해야 한다는 요건이 없을 경우 탐색 방향을 추가하면 상호 의존성이 줄어들도 설계가 단순해진다.
  • 다대다 연관관계의 탐색 방향을 제약하면 훨씬 더 구현하기 쉬운 일대다 연관관계로 줄어든다.
    • 나라-대통령 간의 관계는 양방향 일대다 관계지만, 실용적인 관점에서 단방향 연관관계를 제거할 수 있다.
      ("조지워싱턴이 대통령이었던 나라가 어디입니까?" 라고 물어보진 않는다.)
    • 이것은 연관관계에서 한 방향이 다른 것에 비해 훨씬 의미있고 중요하다는 것을 포착한 것에 해당한다.
    • 도메인을 깊게 이해하다보면 "한정적인(qualifier)" 관계에 이를 때가 많다.
    • 한 나라의 대통령이 한 번에 한 명만 있다는 사실을 깨달으면, 한정자는 다중성을 일대일로 줄인다.

ENTITY(엔티티, 참조객체)

  • 수많은 객체는 본질적으로 해당 객체의 속성이 아닌 연속성과 식별성이 이어지느냐를 기준으로 정의된다.
  • ENTITY의 근본적인 개념은 객체의 생명주기 내내 이어지는 추상적인 연속성이며, 추상적인 연속성은 여러 형태를 거쳐 전달된다.
  • ENTITY 모델링과 설계 상의 고려사항 
    • ENTITY는 자신의 생명주기 동안 형태와 내용이 급격하게 바뀔 수 있지만 연속성은 유지해야 한다.
    • ENTITY를 추적하려면 ENTITY에 식별성이 정의되어 있어야 한다.
    • ENTITY의 클래스 정의와 책임, 속성, 연관관계는 ENTITY에 포함된 특정 속성보다는 ENTITY의 정체성에 초점을 맞춰야 한다.
    • 한 객체가 속성보다는 식별성으로 구분될 경우 모델 내에서 이를 해당 객체의 주된 정의로 삼아라.
    • 클래스 정의를 단순하게 하고 생명주기의 연속성과 식별성에 집중하라.
    • 객체의 형태나 이력에 관계없이 각 객체를 구별하는 수단을 정의하라.
    • 객체의 속성으로 객체의 일치 여부를 판단하는 요구사항에 주의하라.
    • 각 객체에 대해 유일한 결과를 반환하는 연산을 정의하라.
    • 식별 수단은 외부에서 가져오거나 시스템에서 자체적으로 만든 임의의 식별자일 수 있지만, 모델에서 식별성을 구분하는 방법과 일치해야 한다.
    • 모델은 동일하다는 것이 무슨 의미인지 정의해야 한다.
  • 예제 - 경기장 좌석 예약 애플리케이션
    • 좌석과 참가자를 ENTITY로 다룰 수 있다.
    • 지정석인 경우, 각 입장권에는 좌석번호(식별자)가 적혀있을 것이므로 좌석은 ENTITY이다.
    • 일반석인 경우, 개별 좌석은 구분할 필요가 없으므로 좌석은 ENTITY가 아니고 식별자는 필요하지 않다.

ENTITY 모델링

  • ENTITY의 가장 기본적인 책임은 객체의 행위가 명확하고 예측 가능해 질 수 있게 연속성을 확립하는 것이다.
  • ENTITY 객체의 가장 본질적인 특징만으로 정의하고, 그 밖의 객체는 행위와 속성을 검토해서 연관관계에 있는 다른 객체로 옮긴다.
  • 예제 - Customer(고객) 객체
    • 고객 ID는 유일한 식별자
    • 전화번호나 주소는 Customer를 찾거나 일치 여부를 판단하는 데 종종 사용됨
    • 이름은 실별성을 정의하지는 않지만 식별성을 판단하는 수단의 일부로 사용되기도 함

식별 연산의 설계

  • 두 객체가 개념적으로 동일한 ENTITY를 나타내는지 어떻게 알 수 있는가?
    • 어떤 데이터 속성이나 여러 속성의 조합이 시스템 내에서 유일함을 보장받거나 유일하도록 제약되기도 한다.
      • ex) 신문 - 제목, 도시, 발행일로 구분 가능
    • 실질적인 고유키가 없다면 각 인스턴스에 해당하는 클래스 내에 유일한 기호를 덧붙인다. 시스템에서 이러한 ID를 자동으로 만들어내기도 한다.
      • 송장번호나 항공예약번호처럼 생성된 ID가 사용자에게 중요할 수도 있고, 연락처관리 애플리케이션처럼 중요하지 않을 수도 있다.
    • ID의 유일성이 컴퓨터 시스템의 범위를 넘어설 수도 있다.
      • ex) 개별 컴퓨터 시스템을 갖춘 두 병원간의 의료 기록 교환
      • 정부 기간 등 다른 기관에서 발행하는 식별자를 사용해서 구분할 수 있다.

VALUE OBJECT (값 객체)

  • 개념적 식별성이 없는 객체도 많은데, 이러한 객체는 사물의 어떤 특징을 묘사한다.
  • 개념적 식별성을 갖지 않으면서 도메인의 서술적 측면을 나타내는 객체를 VALUE OBJECT 라 한다.
  • VALUE OBJECT는 설계 요소를 표현할 목적으로 인스턴스화되는데, 설계 요소가 어떤 것인지에 대해서는 관심이 없고 해당 요소가 무엇인지에 대해서만 관심이 있다.

  • 예제 - "주소"는 VALUE OBJECT인가요? 누가 묻는거죠?
  • VALUE OBJECT 설계 상의 고려사항
    • 모델에 포함된 어떤 요소의 속성에만 관심이 있다면 VALUE OBJECT로 분류하라.
    • 해당 VALUE OBJECT가 전하는 속성의 의미를 표현하게 하고 관련 기능을 부여하라.
    • VALUE OBJECT는 불변적으로 다뤄라.
    • 아무런 식별성을 부여하지 말고 ENTITY를 유지하는 데 필요한 설계상의 복잡성을 피하라.
  • VALUE OBJECT를 구성하는 속성은 개념적 완정성(conceptual whole)을 형성해야 한다.
    • 도, 시군구, 읍면동, 우편번호 같은 속성은 한 Person 객체의 개별 속성이 되어서는 안된다.
    • 그러한 속성은 하나의 완전한 주소를 구성함으로써 더 단순한 Person과 더 응집력있는 VALUE OBJECT를 만들어낸다.

VALUE OBJECT의 설계

  • VALUE OBJECT의 인스턴스 가운데 어느 것을 사용하는지는 중요하지않다.
  • 이런식으로 제약조건이 줄어들면 설계 단순화나 성능 최적화를 꾀할 수 있다.
  • 하지만 복사, 공유, 불변성에 관한 의사결정이 필요하다.
  • 예제 - 고객 객체
    • 같은 이름을 가진 두 고객 객체의 Name 객체로 하나의 이름 인스턴스를 사용할 수 있다.
    • 하지만 한 사람의 이름이 바뀐다면 다른 사람의 이름도 바뀔 것이다.
    • 이러한 변경을 방지하기 위해서는 해당 객체가 불변적이어야 한다.
  • VALUE OBJECT는 많아지는 경향이 있으므로 성능 최적화를 위한 별도 대안이 필요할 수 있다.
  • 예제 - 주택 설계 소프트웨어
    • 전기 콘센트가 개별 VALUE OBJECT라면 하나의 주택 도면에 수 백개의 VALUE OBJECT가 생긴다.
    • 그러나 콘센트를 모두 상호 교환가능한 것으로 간주한다면 한 콘센트 인스턴스만 공유해서 사용할 수 있다.
  • 복사와 공유 중 어느 것이 더 나은지는 구현환경에 따라 달라진다.
  • 공유가 더 나은 경우
    • 공간을 절약하거나 데이터베이스 내의 객체 수를 줄이는 것이 중요한 경우
    • 통신 부하가 낮은 경우
    • 공유 객체의 불변성이 엄격하게 지켜지는 경우

  • 예제 - VALUE OBJECT를 활용한 데이터베이스 최적화
    • 동일한 데이터에 대해 여러 개의 사본을 저장하는 "역정규화(denormalization)" 기법 
      • 동일한 인스턴스에 대한 객체 참조를 공유하기보다는 해당 인스턴스의 사본을 만드는 식으로 여러 ENTITY의 속성 역할을 하는 VALUE OBJECT는 각 ENTITY가 사용하고 있는 것과 같은 페이지에 저장한다.
      • 저장공간이나 유지보수의 단순함보다는 접근시간이 중요한 경우 사용한다.

VALUE OBJECT를 포함한 연관관계 설계

  • VALUE OBJECT 간의 양방향 연관관계는 논리적으로 타당하지 않다. 어떤 객체가 식별성 없이 자신을 가리키는 동일한 VALUE OBEJCT를 역으로 가리키는 것은 아무 의미가 없다.
  • VALUE OBJECT 간의 양방향 연관관계는 완전히 제거하도록 노력해야 한다.
728x90
Comments