0Pricing
Scala for Backend Engineering & Functional Programming · 강의

도메인 조합하기

더 큰 모델 만들기

도메인 조합하기은(는) CoddyKit의 무료 Scala for Backend Engineering & Functional Programming 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Scala for Backend Engineering & Functional Programming 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

더 큰 모델 만들기

실제 도메인은 더 작은 조각들을 조합하여 만듭니다. 도메인 조합이란 잘 모델링된 ADT, newtype, 검증된 값을 결합하여 더 크면서도 여전히 올바른 구조를 만드는 것을 의미합니다.

  • 작고 특정 목적에 집중된 타입을 더 큰 타입으로 조합할 수 있습니다.
  • 각 조각은 고유한 불변 조건을 유지합니다.
case class Money(cents: Long)
case class Product(name: String, price: Money)

object Main:
  def main(args: Array[String]): Unit =
    println(Product("Book", Money(1999)))

제품 타입 중첩하기

케이스 클래스를 중첩하여 제품 타입을 조합합니다. 각 수준에서 구조를 더하면서도 읽기 쉽게 유지할 수 있습니다.

case class Address(city: String, zip: String)
case class Customer(name: String, address: Address)

object Main:
  def main(args: Array[String]): Unit =
    val c = Customer("Ada", Address("London", "E1"))
    println(c.address.city)

컬렉션으로 조합하기

List, Map, Set을 사용하여 도메인 내부의 일대다 관계를 모델링합니다.

case class Item(name: String, qty: Int)
case class Order(id: Int, items: List[Item])

object Main:
  def main(args: Array[String]): Unit =
    val order = Order(1, List(Item("pen", 2), Item("ink", 1)))
    println(order.items.map(_.qty).sum)

합 타입 조합하기

더 큰 선택지는 더 작은 선택지를 결합하여 만듭니다. 열거형의 한 변형이 또 다른 ADT를 포함할 수 있으므로, 여러 결정을 계층적으로 구성할 수 있습니다.

enum Payment:
  case Card(last4: String)
  case Cash

enum Checkout:
  case Completed(payment: Payment)
  case Abandoned

object Main:
  def main(args: Array[String]): Unit =
    val c: Checkout = Checkout.Completed(Payment.Card("1234"))
    println(c)

도메인을 조합하는 함수

도메인 연산은 입력 타입에서 출력 타입으로 변환하는 순수 함수입니다. 이러한 함수를 조합하면 작업 흐름을 만들 수 있습니다.

case class Cart(total: Long)
case class Receipt(total: Long, tax: Long)

object Main:
  def checkout(c: Cart): Receipt =
    Receipt(c.total, (c.total * 0.2).toLong)

  def main(args: Array[String]): Unit =
    println(checkout(Cart(1000)))

검증 조합하기

각 필드를 스마트 생성자로 만들었다면 for 내포를 사용하여 이들을 조합합니다. 모든 부분이 검증에 성공한 경우에만 전체 객체가 생성됩니다.

object V:
  def name(s: String): Option[String] = if s.nonEmpty then Some(s) else None
  def age(n: Int): Option[Int] = if n >= 0 then Some(n) else None

case class Person(name: String, age: Int)

object Main:
  def make(n: String, a: Int): Option[Person] =
    for nm <- V.name(n); ag <- V.age(a) yield Person(nm, ag)

  def main(args: Array[String]): Unit =
    println(Main.make("Bob", 30))
    println(Main.make("", 30))

복합 데이터 접기

fold 또는 map과 sum을 함께 사용하여 조합된 구조를 집계합니다. 데이터의 형태가 계산 방식을 안내합니다.

case class Line(price: Long, qty: Int)
case class Invoice(lines: List[Line])

object Main:
  def total(inv: Invoice): Long =
    inv.lines.foldLeft(0L)((acc, l) => acc + l.price * l.qty)

  def main(args: Array[String]): Unit =
    val inv = Invoice(List(Line(100, 2), Line(50, 4)))
    println(total(inv))

불변 모델 업데이트하기

변경 사항은 copy로 조합합니다. copy는 선택한 필드를 교체한 새 값을 반환합니다. 원본은 변경되지 않습니다.

case class Account(id: Int, balance: Long)

object Main:
  def deposit(a: Account, amt: Long): Account =
    a.copy(balance = a.balance + amt)

  def main(args: Array[String]): Unit =
    val a = Account(1, 100)
    println(deposit(a, 50))

상태 머신 모델링하기

합 타입과 전이 함수를 조합하여 유효한 전이만 존재하는 상태 머신을 모델링합니다.

enum Light:
  case Red, Green, Yellow

object Main:
  def next(l: Light): Light = l match
    case Light.Red    => Light.Green
    case Light.Green  => Light.Yellow
    case Light.Yellow => Light.Red

  def main(args: Array[String]): Unit =
    println(next(Light.Red))
    println(next(Light.Green))

도메인과 연산을 계층화하기

데이터 타입은 순수하게 유지하고 동작은 함수나 메서드에 둡니다. 조합된 모델과 변환 집합을 함께 사용하면 작은 도메인 라이브러리가 됩니다.

case class Temp(celsius: Double):
  def toF: Double = celsius * 9 / 5 + 32

object Main:
  def main(args: Array[String]): Unit =
    val t = Temp(25.0)
    println(t.toF)

모두 조합하기

완전한 모델은 newtype, 제품 타입, 합 타입, 컬렉션, 검증된 생성을 조합합니다. 그 결과 잘못 사용하기 어렵고 추론하기 쉬운 모델을 얻을 수 있습니다.

  • 먼저 작은 타입을 만듭니다.
  • 이를 조합하여 집합체를 만듭니다.
  • 연산을 순수 함수로 표현합니다.
case class Sku(value: String)
case class Line(sku: Sku, qty: Int)
case class Basket(lines: List[Line]):
  def count: Int = lines.map(_.qty).sum

object Main:
  def main(args: Array[String]): Unit =
    val b = Basket(List(Line(Sku("A"), 2), Line(Sku("B"), 3)))
    println(b.count)

빠른 확인

도메인 조합에 대한 이해도를 확인해 보세요.

복습

도메인을 조합하는 방법을 배웠습니다.

  • 제품 타입과 합 타입을 중첩하여 풍부한 구조를 모델링합니다.
  • 컬렉션을 사용하여 일대다 관계를 표현합니다.
  • for 내포로 검증을 조합합니다.
  • copy로 불변성을 유지하며 업데이트합니다.
  • 데이터는 순수하게 유지하고 연산은 함수로 표현합니다.
case class User(id: Int, name: String)
case class Post(author: User, text: String)

object Main:
  def main(args: Array[String]): Unit =
    val p = Post(User(1, "Ada"), "hello")
    println(p.copy(text = "hi"))

자주 묻는 질문

“도메인 조합하기” 강의는 무료인가요?

네 — “도메인 조합하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Scala for Backend Engineering & Functional Programming 강의 전체를 잠금 해제할 수 있습니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

“도메인 조합하기”에서 뭘 배우나요?

더 큰 모델 만들기 브라우저에서 직접 실행하는 실습 코드로 Scala for Backend Engineering & Functional Programming을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Scala for Backend Engineering & Functional Programming을(를) 시작하는 데 경험이 필요한가요?

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

“도메인 조합하기” 강의는 얼마나 걸리나요?

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

이 Scala for Backend Engineering & Functional Programming 강의에서 코드를 작성하고 실행할 수 있나요?

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

이 강의의 모든 강의

  1. ADT로 모델링하기
  2. 스마트 생성자
  3. 새 타입
  4. 도메인 조합하기
← Scala for Backend Engineering & Functional Programming(으)로 돌아가기