
도메인(Domain)이란, 사용자가 프로그램을 사용하는 주제 영역, 또는 사용자가 프로그램을 사용해서 해결하고 싶은 문제들의 집합을 말한다.
좀 더 풀어서 설명하자면, 도메인을 소프트웨어로 구현해야 하는 요구 사항의 범위로 생각하면 된다. 소프트웨어를 구현할 때 모든 요구 사항을 코드로 옮기는 건 현실적으로 불가능할 것이다. 따라서 어떤 요구 사항을 코드로 구현하고 제외 시킬지 정해야 하는데 이렇게 정해진 요구 사항의 범위를 도메인이라고 생각하면 된다.
이해를 돕기 위해 음식 배달 도메인을 예로 들어보자. 먼저, 지금같이 배달의 민족이나 쿠팡 이츠와 같은 애플리케이션을 이용하는 것이 아니라, 옛날처럼 매장에 직접 전화를 걸어 원하는 메뉴와 배달 받을 주소지를 알려줬던 시절을 떠올려보자. 그때 우리는 아래와 같이 절차를 거쳐서 음식을 주문했다.
사용자가 음식을 주문하기 위해서는 식당의 전화번호와 메뉴를 알아야 한다.
식당들은 사용자가 주문할 수 있도록 메뉴와 연락처가 수록된 전단지를 배포했을 것이다.
사용자들은 이 전단지를 보고 식당에 전화를 걸어 원하는 메뉴와 배달할 주소지를 알려준다.
식당은 주문된 메뉴를 조리한 후에 배달원을 통해 음식을 사용자의 집으로 배달한다.
사용자는 음식을 받은 후에 음식값을 결제하고 배달된 음식을 맛있게 먹는다.
하지만 이렇게 전화로 음식을 주문하는 경우, 주문한 음식과 다른 엉뚱한 음식이 배달되거나 다른 주소지로 잘못 배달될 수도 있고, 주문 자체가 누락되는 문제가 발생할 수 있다. 이런 불편함을 없애기 위해 배달 애플리케이션을 만든다고 해보자.
배달앱을 만들기로 결정했다면 요구 사항 중에서 소프트웨어로 구현해야 하는 범위를 결정해야 한다. 음식을 조리 하거나 음식을 배달하거나 식사를 하는 단계는 애플리케이션 안에 구현하기도 힘들 뿐더러 구현할 필요가 없다. 따라서 이 단계들은 구현 범위에서 제외 시키고 메뉴를 표시하고, 메뉴를 주문하고, 주문된 음식을 결제하는 단계만 포함시켜야 한다. 이렇게 구현하기로 결정한 요구 사항의 범위가 음식 배달 시스템의 도메인이 된다.
이렇게 소프트웨어 안에 포함 시킬 요구 사항의 범위를 정했다면, 이제 요구 사항들을 분석해야 한다. 도메인 안에 존재하는 중요한 개념들을 이용해서 요구 사항을 분석하고 이 개념들을 기반으로 시스템을 구현하는데 필요한 객체들을 식별할 수 있다.
이제 사용자가 쉽고 빠르게 보고 싶은 영화를 예매할 수 있는 간단한 영화 예매 시스템을 설계한다고 해보자.
영화 예매 도메인에서 가장 중요한 개념은 당연히 "영화" 일 것이다. 영화는 영화의 제목, 러닝 타임, 감독, 배우와 같이 영화라고 할 때 일반적으로 떠올리는 다양한 정보들을 포함한다.
영화는 사용자가 예매하고 싶은 영화가 무엇인지 서술하지만, 실제로 사용자들이 예매하는 대상은 "영화" 가 아니라 "상영" 이다. 상영은 사용자들이 관람할 수 있도록 특정한 시간에 영화를 공개하는 활동을 의미한다. 상영에는 상영 날짜, 상영 시간, 상영 회차가 포함된다. 사용자가 상영을 예매하게 되면, 시스템은 예매 요금을 계산해서 사용자에게 청구해야 한다. 영화의 정가만 이용해서 예매 요금을 계산하면 너무 간단해지기 때문에 사용자가 특정한 조건을 만족시키는 경우에 예매 요금을 할인해 줄 수 있다는 요구 사항을 추가해보자.
영화 예매 도메인에서 "할인" 은, "할인 정책(DiscountPolicy)” 과 “할인 조건(DiscountCondition)” 의 조합으로 구성된다. 할인 정책은 사용자의 예매 요금에서 차감할 할인 금액을 계산하는 방법을 의미한다. 첫 번째 할인 정책은 "금액 할인 정책(AmountDiscountPolicy)" 이다. 금액 할인 정책은 항상 동일한 금액을 할인해주는 방식이다. 두 번째 할인 정책으로 "비율 할인 정책(PercentDiscountPolicy)" 이 있다. 비율 할인 정책은 영화의 정가에서 일정한 비율을 할인해주는 방식이다.
할인 금액을 계산하기 위해서는 할인 정책 뿐만 아니라 할인 조건도 함께 고려해야 한다. 할인 조건은 말 그대로 요금을 할인 받기 위해 만족해야 하는 조건을 정의한다. 할인 조건에는 순서 조건, 기간 조건 총 2가지가 있다고 가정해보자.
먼저 "순서 조건(SequenceCondition)" 은 상영의 회차를 기준으로 할인 여부를 판단한다. "기간 조건(PeriodCondition)" 은 상영의 시작 시간을 기준으로 할인 여부를 판단한다. 이제 영화와 할인 정책, 할인 조건 사이의 관계에 초점을 맞춰보도록 하자.

사용자가 상영을 예매할 때마다 시스템은 할인 금액을 계산하기 위해 할인 정책과 할인 조건을 조합한다. 할인 조건에 설정된 기준에 따라 할인을 적용할지 판단하고, 만약 할인이 가능하다면 할인 정책을 기반으로 할인 금액을 계산하게 된다. 이때 영화, 할인 정책, 할인 조건 사이에는 연결될 수 있는 개념의 수를 제약하는 특정한 규칙이 존재한다.
이렇게 도메인 개념들 사이에 연결 가능한 숫자의 범위를 "다중성" 이라고 부르고, 도메인 개념들을 연결한 선 아래의 숫자로 표기한다.
영화 예매 시스템의 다중성을 자세히 살펴보자.

먼저 영화와 할인 정책 사이의 다중성을 보면 영화에는 1, 할인 정책에는 0 ~ 1 사이의 범위 값이 명시되어 있다. 할인 정책에는 0 ~ 1 사이의 범위가 표기되어 있는데, 하나의 영화에 대해 할인 정책이 아예 없거나, 있다면 최대 1개까지만 존재할 수 있다는 사실을 의미한다. 영화에 표기되어 있는 1은, 할인 정책이 존재할 경우, 영화는 항상 1개가 존재해야 한다는 것을 의미한다. 영화에 할인 정책이 존재하지 않는다면 할인이 제공되지 않는 영화를 의미하고, 할인 가능하다면 할인 정책은 하나만 존재할 수 있기 때문에 금액 할인 정책과 비율 할인 정책 중 하나만 연결할 수 있는 것이다.
이번에는 할인 정책과 할인 조건 사이의 다중성을 살펴보자.

할인 정책에는 1, 할인 조건에는 1 ~ 사이의 범위 값이 명시되어 있습니다. 할인 조건에 붙은 1 ~ 사이의 범위는 하나의 할인 정책에 대해 할인 조건은 반드시 최소 1개는 존재해야 하고, 하나 이상 존재하는 것도 가능하다는 것을 의미한다. 할인 정책에는 1이 표기되어 있기 때문에 할인 조건이 존재할 경우, 할인 정책은 항상 1개가 존재해야 한다.
이제 영화와 할인 정책, 할인 조건을 함께 모아서 살펴보자.

위쪽에는 영화, 할인 정책, 할인 조건 사이의 관계가 그려져 있고, 아래쪽에는 개념 사이의 다중성을 기반으로 만들어질 수 있는 영화의 예시를 표현했다. 현재 “한산” 이라는 영화에는 1000원을 할인해주는 금액 할인 정책이 연결되어 있기 때문에 주어진 4가지의 할인 조건 중에 하나라도 만족할 경우에는 정가에서 1000원이 차감되게 된다.
이제 전체적인 도메인 개념을 하나씩 정리해보자.

먼저 영화는 영화의 기본 정보를 담고 있는 가장 중심이 되는 개념이다. 영화에 할인 정책이 있다면 사용자에게 할인을 제공할 수 있다. 할인 정책은 할인 금액을 계산하는 규칙을 정의하는 개념으로, 고정 금액을 할인하는 금액 할인 정책과 비율로 할인 금액을 계산하는 비율 할인 정책의 두 가지 종류가 존재한다.
하나의 할인 정책에는 할인 조건이 최소 한 개는 존재해야 하고, 여러 개의 할인 조건을 연결하는 것도 가능하다. 할인 조건은 할인 여부를 판단하는 규칙을 의미하고, 상영 회차를 기준으로 할인 여부를 판단하는 순서 조건과 상영 시작 시간을 기준으로 할인 여부를 판단하는 기간 조건에 두 가지가 있다. 상영은 사용자가 실제로 예매하는 대상이고, 여러 시간에 걸쳐 반복적으로 상영 가능하기 때문에 영화에 대해 여러 개의 상영이 연결될 수 있다.
예매는 사용자가 상영을 구매하면 생성되는 도메인 개념을 가리킨다. 여러 명의 사용자가 동시간대에 상영되는 영화를 함께 관람할 수 있기 때문에 하나의 상영에 대해 여러 개의 예매가 생성될 수 있다.