Skip to content

1.1 도메인 주도 설계란?: 설계의 개념을 이해하기 위한 기초 지식 #1526

@jongfeel

Description

@jongfeel

1.1 도메인 주도 설계란?: 설계의 개념을 이해하기 위한 기초 지식

1.1.1 들어가기 전에

도메인 주도 설계의 확산

<도메인 주도 설계>(위키북스, 2011)는 거의 20년 전에 출간되었습니다.
기술서로는 비교적 오래된 책이라 할 수 있습니다.
출간 초기에는 객체지향 소프트웨어 개발자를 중심으로 상당한 반향을 일으켰습니다.

최근 들어 마이크로서비스 등 분산 아키텍처 설계에 도메인 주도 설계 기법을 도입하거나 애자일 제품 개발을 위한 접근법으로 도메인 주도 설계를 참고하는 경우가 많아지고 있습니다.
20년 전과 달리 객체지향 프로그래밍이 보편화된 것도 도메인 주도 설계가 널리 관심을 받게 된 이유 중 하나일 것입니다.

1.1.2 도메인 주도 설계의 개념 이해하기

도메인 주도 설계가 전제하는 개념은 다음과 같습니다.

  • 비즈니스의 지속과 발전 -> 필요하다
  • 발전과 변화를 계속하는 소프트웨어 -> 초점을 맞춘다
  • 복잡한 업무 로직 -> 활용한다
  • 도메인 모델

비즈니스 활동의 발전과 소프트웨어 설계

도메인이란 소프트웨어가 대상으로 하는 영역입니다.
업무용 애플리케이션이라면 비즈니스 활동 자체가 도메인입니다.

애플리케이션의 대상 영역인 비즈니스 활동이나 업무 내용을 먼저 이해하는 것은 소프트웨어 개발에 있어서 당연한 것으로, 도메인 주도 설계만의 고유한 개념은 아닙니다.
도메인 주도 설계는 비즈니스 환경이 변하고 발전하는 동안에도 계속해서 존속하는 것을 목표로 합니다.

<도메인 주도 설계>란 계속 진화하는 소프트웨어를 만들어 내기 위한 개념과 설계 방식을 에릭 에반스의 지식과 경험을 기초로 정리한 것입니다.

도메인의 복잡성에 초점을 맞추기

에반스는 소프트웨어가 복잡해지는 근본적인 원인이 소프트웨어가 대상으로 하는 영역(도메인)의 복잡성 때문이라고 생각했습니다.
그래서 업무용 애플리케이션을 개발할 때는 업무 프로세스와 업무 규칙을 이해하고, 이를 바탕으로 소프트웨어를 개발하는 것이 핵심 과제라고 말합니다.

도메인 주도 설계는 개발자에게 생소한 업무 영역을 대상으로 애플리케이션을 개발할 때 사용하는 개념과 설계 방식입니다.

1.1.3 도메인 모델을 활용하기

도메인 주도 설계에서는 복잡한 업무 규칙이 적용된 소프트웨어를 쉽고 안전하게 변경하기 위해 도메인 모델을 사용합니다.

도메인 주도 설계는 가벼운 대화나 대략적인 스케치(Rough Sketch) 등을 중시합니다.
또한 형식적으로 모델을 표현하는 데에 프로그래밍 언어를 사용합니다.
모델을 소스 코드로 표현하기를 중시하는 것도 도메인 주도 설계의 한 가지 특징입니다.

1.1.4 도메인 지식을 내재화하기

복잡한 업무 규칙을 이해하고 소프트웨어를 개발하려면 개발자는 해당 사업의 업무 방식을 이해하고 있어야 합니다.

여러 기초적인 도메인 지식을 습득해 다음의 문장으로 나타낼 수 있다면 코드 몇 줄로 쉽게 작성할 수 있을 것입니다.

  • 오버부킹 규칙: 화물 크기의 총합은 적재량의 110%까지만 예약할 수 있다.

지속적인 학습과 깊이 있는 이해

도메인에 대해 지속적으로 학습하고 요구사항을 파악하는 것은 소프트웨어 개발에서 중요한 활동입니다.
요구사항이 구체적이고 상세하게 작성되어 있으면 소프트웨어로 업무 규칙을 구현하는 것 자체는 그리 어렵지 않습니다.
거기까지 이해할 수 있으면 소프트웨어 설계의 품질이 크게 향상될 것입니다.

1.1.5 의사소통할 때 공통 언어 사용하기

용어와 표현이 다를 경우

일반적인 업무 용어와 특정 기업 내부에서 사용하는 용어가 일치하지 않을 수도 있고, 부서 간에 사용하는 용어가 다를 수도 있습니다.
부서 간 담당자가 같은 용어를 사용한다고 하더라도 업무를 바라보는 관점이나 중요하게 생각하는 부분이 다를 수도 있습니다.

유비쿼터스 언어

유비쿼터스(ubiquitous)는 ‘언제 어디서나’라는 의미의 단어입니다.
업무 전문가와 소프트웨어 개발 전문가가 서로 다른 용어를 사용하는 것이 아니라, 소프트웨어 개발의 다양한 활동을 통해 일관되게 ‘같은 용어를 사용해 소프트웨어를 개발하자’라고 하는 것입니다.

중요한 용어들을 선별합니다.
선별한 용어를 모두가 의식적으로 사용하면, 그 용어가 중심이 되어 그 주변 용어도 일치하게 된다는 것이 도메인 주도 설계에서 말하는 유비쿼터스 언어의 개념입니다.
이렇게 중심이 되는 용어들의 집합이 바로 도메인 모델입니다.

유비쿼터스 언어는 개발자 간의 대화, 소스 코드의 클래스 이름이나 메서드 이름, 커밋 로그 등에도 사용됩니다.

대량의 정보 정리하기

단순한 모델을 통해, 같은 용어를 같은 의미로 사용하게 됨으로써 소프트웨어를 더 잘 개발할 수 있다는 것이 도메인 주도 설계의 개념입니다.

1.1.6 모델과 구현을 연결하기

<도메인 주도 설계>에서는 지식의 정리와 인식을 일치시키기 위해 사용하는 모델을 프로그램 기본 구조에 그대로 적용하자고 제안합니다.

‘모델과 설계는 상호 연관되어 있다’는 일반적인 의미가 아니라 ‘모델과 구현은 연결되어야 한다’는 의미입니다.

모델과 구현을 연결하는 구체적인 설계 패턴으로는 값 객체, 애그리게이트 등이 있습니다.

1.1.7 애플리케이션 개발과 도메인 주도 설계

도메인 주도 설계에서는 애플리케이션 전체의 설계와 복잡한 업무 로직의 설계를 다음과 같이 접근합니다.

  • 복잡한 업무 로직을 독립적인 구성 요소로 분리한다.
  • 애플리케이션의 다른 구성 요소가, 업무 로직을 표현하는 구성 요소에 의존하게 설계한다.

화면, 데이터베이스, 통신의 세부 사항 중에서 업무 로직과 직접적으로 관련된 부분에 초점을 맞추고, 그렇지 않은 부분은 따로 구분하여 생각합니다.

업무 로직을 독립적인 구성 요소로 만들기

도메인 주도 설계에서는 아래 관심사에서 업무 로직을 분리해 독립시킵니다.

  • 데이터 저장 및 참조
  • 네트워크 통신을 통한 알림과 데이터 전송
  • 화면을 이용한 표현 및 입력

업무 로직을 알기 쉽게 정리하고, 소프트웨어로 작성하기 위해 업무 로직에만 집중합니다.

다른 요소가 업무 로직에 의존하게 하기

도메인 모델과 다른 요소들을 연결하는 방법에는 다음과 같은 다양한 개념이 있습니다.

  • 도메인 모델 + 3계층 구조
  • 도메인 모델 + 포트 & 어댑터
  • 클린 아키텍처

기본적으로 도메인 모델을 중심으로 한다는 점에서는 같지만, 도메인 모델과 어떻게 연관시킬 것인가에 대해서는 개념의 차이가 있습니다.

도메인 모델 + 3계층 구조

기존의 3계층 구조를 기반으로 도메인 모델을 분리하여 독립시키는 패턴입니다.
다른 구성 요소가 도메인 모델(업무 로직)을 직접 이용하는 것에 중점을 둡니다.

헥사고날 아키텍처(도메인 모델 + 포트 & 어댑터)

애플리케이션의 구성 요소를, 핵심인 코어와 주변부인 어댑터들로 분리하는 개념이며, <도메인 주도 설계>가 등장하기 이전에도 있었습니다.

도메인 모델을 핵심으로 하고, 다른 애플리케이션의 구성 요소와 분리하는 ‘포트와 어댑터’ 개념은 도메인 주도 설계로 애플리케이션을 개발할 때 좋은 선택이 될 수 있습니다.

각각의 구성 요소들을 어댑터로 일반화하고 포트로 애플리케이션의 코어와 연결하는 방식입니다.

클린 아키텍처

설계 원칙으로서 클린 아키텍처의 개념은 다음과 같이 매우 단순합니다.

  • 관심사를 분리하는 것
  • 분리된 구성 요소의 의존 관계를 단순하게 만드는 것

경계를 철저하게 분리하려면 각각의 경계에 인터페이스를 선언하여 상위 계층이 하위 계층에 의존하는 관계를 단순하게 만들어야 합니다.
또한 경계를 넘나들 때 동일한 데이터 구조에 의존하지 않도록, 외부에서 내부로 전달할 데이터 구조와 내부에서 외부로 전달할 데이터 구조를 각각 정의하고 경계를 넘나들 때 변환하도록 해야 합니다.
이렇게 하면 경계 간의 의존 관계를 최대한 줄일 수 있습니다.

<클린 아키텍처>에서는 업무 로직을 엔터티 클래스에 자연스럽게 포함합니다.
반면 <도메인 주도 설계>의 엔터티는 개체를 식별하기 위한 클래스로 사용되며, 계산과 판단을 위한 업무 로직은 포함하지는 않습니다.
도메인 주도 설계에서는 계산과 판단 로직은 값 객체나 애그리게이트에 구현합니다.

데이터 입출력과 업무 로직의 분리

업무 로직과 관련 없는 단순한 데이터 입출력이나 데이터 저장 등을 처리하기 위한 도메인 주도 설계의 개념은 다음과 같습니다.

  • 업무 로직에 초점을 맞추고, 그와 관련된 화면, 테이블, 통신을 중점적으로 설계한다.
  • 그 이후에 단순한 기능이나 업무 로직과 관련이 적은 데이터 처리 기능을 점차 추가한다.

이것을 한 단계 더 분리하는 것이 업무 로직에 초점을 맞추는 도메인 주도 설계의 개발 방식입니다.

구체적으로는 다음과 같은 기법으로 설계할 수 있습니다.

  • 업무 로직을 표현하는 클래스와 그렇지 않은 클래스를 엄격하게 분리한다.
  • 업무 로직을 표현하는 클래스만 도메인 모델에 넣는다.
  • 필요한 경우, 두 클래스를 합성하기 위한 클래스를 만든다.
  • 합성을 위한 컴포지트 클래스(composite class)는 도메인 모델 외부에 둔다.
  • 컴포지트 클래스는 여러 개의 객체를 조합하거나 변환하는 역할을 수행한다.

단순한 입출력 기능과 핵심 업무 로직을 분리하기 위해 메서드나 클래스를 이동하는 것과 같은 리팩터링을 자주 하는 것이 도메인 주도 설계의 개발 방식입니다.
이러한 리팩터링을 지속적으로 수행하다 보면 업무 지식에 대한 이해도가 점점 높아지고 숨겨진 개념을 명확하게 표현하는 방법에 더욱 능숙해질 것입니다.

1.1.8 도메인 주도 설계와 객체지향 프로그래밍

클래스나 타입(Type)을 사용한 <도메인 주도 설계>의 접근법을 실천하고 싶다면 자바와 같이 비즈니스 애플리케이션에서 개발 사례가 많은 언어를 사용해야 관련된 정보를 접하기 쉬울 것입니다.

<도메인 주도 설계>의 접근 방법은 베르트랑 메예르(Bertrand Mayer)의 (Prentice Hall, 1988)에서 말하고 있는, 다음과 같은 개념의 영향도 큰 것 같습니다.

  • 소프트웨어의 분해는 기능이 아닌 타입을 기준으로 하는 것이 좋다.
  • 타입은 클래스를 기반으로 한다.
  • 클래스를 유일한 모듈로 한다.

간단히 말하면 클래스와 타입, 모듈을 일치시키는 설계 접근법으로, 자바는 이 개념에 가까운 프로그래밍 언어라고 할 수 있습니다.

1.1.9 도메인 주도 설계와 애자일 소프트웨어 개발

리팩터링과 고객과의 빈번한 대화를 중심으로 하는 XP의 방식이 <도메인 주도 설계>의 개념과 설계 방식을 구현하는 데 가장 적합하다고 생각합니다.

리팩터링이나 고객과의 빈번한 대화를 중심으로 하는 방식을 비교한다면, 도메인 주도 설계를 도입했을 때의 효과, 품질, 속도 면에서 큰 차이가 있을 것 같습니다.

1.1.10 요약

  • 도메인 주도 설계는 비즈니스와 함께 성장하고 발전하는 소프트웨어를 만들기 위한 개념과 설계 방식입니다.
  • 이를 위해 업무 로직에 초점을 맞추고, 도메인 모델을 ‘업무 지식의 정리’, ‘의사소통을 위한 기본 용어’, ‘클래스 설계의 기본 구조’라는 세 가지의 용도로 활용합니다.
  • 전체 애플리케이션에서 업무 로직을 표현하는 도메인 모델을 다른 구성 요소와 명확하게 분리합니다.
  • 도메인 주도 설계의 설계 방식은 타입, 클래스, 모듈을 일치시키고, 관련 업무 데이터와 업무 로직을 클래스로 캡슐화하는 객체지향 프로그래밍입니다.
  • 개발 방식으로는 의사소통과 리팩터링이 활발하게 이루어지는 XP의 증분형 설계가 가장 적합합니다.

Metadata

Metadata

Assignees

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions