0Pricing
TypeScript Academy · 강의

도메인 모델링 — 집합체, 불변 조건과 서비스

브랜드가 있는 ID를 사용해 Cart 같은 집합체를 모델링하고 팩토리와 서비스로 불변 조건을 강제합니다.

도메인 모델링 — 집합체, 불변 조건과 서비스은(는) CoddyKit의 무료 TypeScript Academy 강의입니다. 이것은 3개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 TypeScript Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

소개

목표: 브랜드가 붙은 ID를 사용해 Cart 집계를 모델링하고, 수량 > 0 같은 규칙이 팩토리와 서비스에서 적용되도록 합니다.

  • 브랜드가 붙은 ID로 엔터티 경계 구분
  • 팩토리가 결과 유니언 반환
  • 서비스 함수가 잘못된 상태 전이를 방지

엔터티 및 브랜드

브랜드가 붙은 ID를 사용하면 CartId와 ProductId는 둘 다 문자열이어도 서로 호환되지 않습니다. 이를 통해 혼동을 방지합니다.

type Brand<Tag extends string, T> = T & { readonly __brand: Tag }

type CartId = Brand<"CartId", string>
type ProductId = Brand<"ProductId", string>

type Result<T> = { ok: true; value: T } | { ok: false; error: string }

const cartId = (s: string): CartId => s as CartId
const productId = (s: string): ProductId => s as ProductId

집계 및 불변식

팩토리가 규칙을 검증합니다. 수량은 > 0이어야 합니다. 유효한 Line 객체만 만들 수 있습니다.

type Money = number & { readonly __brand: "Money" }
const money = (n: number): Money => n as Money

interface Line { productId: ProductId; qty: number; price: Money }
interface Cart { id: CartId; lines: Line[]; total: Money }

function makeLine(productId: ProductId, qty: number, price: Money): Result<Line> {
  if (!Number.isInteger(qty) || qty <= 0) return { ok: false, error: "qty must be > 0" }
  return { ok: true, value: { productId, qty, price } }
}

function makeCart(id: CartId): Cart { return { id, lines: [], total: money(0) } }

서비스: 항목 추가

서비스 함수는 안전한 상태 전이를 수행하고 합계를 다시 계산합니다. 합계가 유효하지 않으면 상태를 손상시키는 대신 함수가 error를 반환합니다.

function addItem(cart: Cart, line: Line): Result<Cart> {
  const lines = [...cart.lines, line]
  const totalNum = lines.reduce((s, x) => s + (x.qty * (x.price as number)), 0)
  if (!Number.isFinite(totalNum) || totalNum < 0) return { ok: false, error: "invalid total" }
  return { ok: true, value: { ...cart, lines, total: (totalNum as unknown) as Money } }
}

// Usage
const c0 = makeCart(cartId("c1"))
const l = makeLine(productId("p1"), 2, money(10))
const c1 = l.ok ? addItem(c0, l.value) : { ok: false, error: "bad line" }

경계 매핑

경계(예: APIs)에서는 데이터 전송 객체로 변환하고, 다시 구문 분석할 때 검증합니다. 팩토리가 데이터의 정확성을 보장합니다.

type CartDTO = { id: string; lines: { productId: string; qty: number; price: number }[]; total: number }

function serialize(c: Cart): CartDTO {
  return {
    id: c.id as unknown as string,
    lines: c.lines.map(x => ({ productId: x.productId as unknown as string, qty: x.qty, price: x.price as unknown as number })),
    total: c.total as unknown as number
  }
}

function parse(dto: CartDTO): Result<Cart> {
  const id = cartId(dto.id)
  const lines: Line[] = []
  for (const raw of dto.lines) {
    const l = makeLine(productId(raw.productId), raw.qty, money(raw.price))
    if (!l.ok) return { ok: false, error: l.error }
    lines.push(l.value)
  }
  const totalNum = lines.reduce((s, x) => s + (x.qty * (x.price as number)), 0)
  return { ok: true, value: { id, lines, total: money(totalNum) } }
}

팁

권장 사항:

  • 검증을 팩토리에 중앙화하십시오.
  • 서비스 함수는 순수하고 결정적으로 유지하십시오.
  • 브랜드 변환은 시스템 경계에서만 수행하십시오.

불변식 확인

빠른 확인: 수량 > 0 같은 불변식은 어떻게 적용해야 합니까?

복습

복습: 브랜드가 붙은 ID를 팩토리 및 서비스와 결합하면 불변식을 적용할 수 있습니다. 모든 진입점에서 입력을 검증하므로 유효하지 않은 상태는 만들 수 없습니다.

자주 묻는 질문

“도메인 모델링 — 집합체, 불변 조건과 서비스” 강의는 무료인가요?

네 — “도메인 모델링 — 집합체, 불변 조건과 서비스” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 TypeScript Academy 강의 전체를 잠금 해제할 수 있습니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

“도메인 모델링 — 집합체, 불변 조건과 서비스”에서 뭘 배우나요?

브랜드가 있는 ID를 사용해 Cart 같은 집합체를 모델링하고 팩토리와 서비스로 불변 조건을 강제합니다. 브라우저에서 직접 실행하는 실습 코드로 TypeScript Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

TypeScript Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 TypeScript Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 3번째 강의입니다.

“도메인 모델링 — 집합체, 불변 조건과 서비스” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 TypeScript Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 TypeScript Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 단위 혼동을 방지하는 브랜딩·불투명 타입
  2. 태그가 있는 ID와 도메인 모델링 패턴
  3. 도메인 모델링 — 집합체, 불변 조건과 서비스
← TypeScript Academy(으)로 돌아가기