Today I Learned

[도메인 주도 설계] 10. 유연한 설계 (2) 본문

도메인 주도 설계

[도메인 주도 설계] 10. 유연한 설계 (2)

하이라이터 2022. 2. 17. 22:36
728x90

CONCEPTUAL CONTOUR (개념적 윤곽)

  • 도메인에 완벽한 일관성이 존재하는 것은 아니지만 나름의 논리와 잠재적인 일관성이 존재한다.
  • 설계 요소(연산, 인터페이스, 클래스, AGGREGATE)를 응집력 있는 단위로 분해하고, 계속적인 리팩터링을 토대로 변경되는 부분과 변경되지 않는 부분을 나누는 중심축을 식별할 수 있다.
  • 변경을 분리하기 위한 패턴을 명확하게 표현하는 CONCEPTUAL CONTOUR를 찾을 수 있다.

  • 예제 - 발생(Accrual)의 윤곽
    • 9장에서 리팩터링한 모델은 기존 모델에 비해 객체를 하나 더 포함하고 있지만 책임 분할은 크게 바뀌지 않았다.
    •  별도로 유지됐던 수수료와 이자 상환은 하나로 모이고, Caculator 클래스의 조건 로직을 통해 만들어지던 Schedule은 수수료와 이자 유형에 따라 여러 개의 개별 클래스로 나뉘었다.
    • Accrual Schdule 계층 구조의 응집력 때문에 이 모델이 도메인의 CONCEPTUAL CONTOUR를 더 잘 반영하는 것으로 보인다.
  •  예상치 못한 변화
    • 이전 설계라면 두 Payment History 클래스 간에 중복이 발생했을 조기상환 및 연체 상환 처리에 대한 새로운 요구사항들도 새로운 모델의 Payment 클래스에서는 동일하게 적용된다.

STANDALONE CLASS (독립형 클래스)

  • 상호의존성은 모델과 설계를 이해하기 어렵게 만들며, 테스트를 어렵게 만들고 유지보수성을 떨어뜨린다. 그리고 쉽게 축적되는 경향이 있다.
  • MODULE과 AGGREGATE는 지나친 상호의존성을 방지하는 목적이지만, MODULE 내에서조차 의존성이 증가할수록 설계를 파악하는데 어려움이 커진다.
  • 낮은 결합도를 개념적 과부하를 줄이는 기본적인 방법 중 하나이며, STANDALONE CLASS는 극단적으로 결합도를 낮춘 것이다.

CLOSURE OF OPERATION (연산의 닫힘)

  • 어떤 집합 S에서 임의의 원소 2개를 뽑아서 어떤 연산을 한 결과가 항상 집합 S의 원소일때, 집합 S는 그 연산에 대해 닫혀있다고 표현한다.
  • 반환 타입과 인자 타입이 동일한 연산을 정의한다. 구현자(implementer)가 연산에 사용되는 상태를 포함하고 있다면 인자 타입과 반환 타입을 구현자의 타입과 동일하게 정의한다. 이런 방식으로 정의된 연산은 해당 타입의 인스턴스 집합에 닫혀있다. 닫힌 연산은 부차적인 개념을 포함하지 않고도 고수준의 인터페이스를 제공한다.

  • 예제 - 컬렉션에 포함된 요소의 선택
    • 자바에서는 Collection에 포함된 일부 요소를 선택하기 위해 Iterator에 요청을 보낸다. 그리고 조건에 만족하는 요소를 새로운 Collection에 추가한다.
      Set employees = (Employee 객체로 구성된 Set);
      Set lowPaidEmployees = new HashSet();
      Iterator it = employees.iterator();
      while (it.Next()) {
        Employee an Employee = it.next();
        if (anEmployee.salary() < 40000)
          lowPaidEmployees.add(anEmployee);
      }
    • 이것은 개념상 어떤 집합의 부분 집합을 선택한 것이다. Iterator는 불필요하게 수반되는 추가개념이다.
      스몰토크라면 어떤 이질적인 개념도 추가하지않고 부분집합을 선택했을 것이다.
      employees := (Employee 객체로 구성된 Set).
      lowPaidEmployees := employees select:
        [:anEmployee | anEmployee salary < 40000].​

선언적 설계

  • 선언적 설계는 일종의 실행 가능한 명세로서 프로그램을 작성하는 방식을 의미한다. 특성을 정확하게 기술함으로써 소프트웨어를 제어하는 것이다.
  • 선언적 설계는 MODEL-DRIVEN DESIGN이 지향하는 방식이지만, 주의할 점이 있다.
    • 필요한 모든 것을 충분하게 표현할 수 없는 선언 언어와 자동화로 감당할 수 있는 범위를 벗어나면 소프트웨어를 확장하기가 어려움 프레임워크
    • 자동으로 생성된 코드와 직접 작성한 코드를 통합한 후 코드를 다시 생성할 경우 통합한 부분이 없어져서 반복된 주기를 무력하게 만드는 코드 생성 기법
  • 여러 선언적인 접근법은 우회할 경우 변질될 가능성이 있다. 선언적 프로그램의 이점을 누리기 위해서는 모든 개발자가 프레임워크 규칙을 준수해야 한다.

도메인 특화 언어

  • 도메인 특화 언어에서는 특정 도메인을 위해 구축된 특정 모델에 맞게 조정된 프로그래밍 언어를 사용에 클라이언트 코드를 작성한다.
  • 이러한 언어는 프로그램의 표현력을 월등히 향상시킬 수 있고 UBIQUITOUS LANGUANGE와도 높은 일관성을 유지할 수 있다.
  • 하지만 언어를 수정하기 어렵고, 수정된 모델과 도메인 특화 언어를 준수하도록 클라이언트 코드를 리팩터링하기 어렵다.
728x90
Comments