04. DTO, Domain

Eunjin·2025년 12월 12일

Spring Boot

목록 보기
3/4

01. DTO (Data Transfer Object)

  • 목적 : 계층 간 "데이터 전달"을 위해
    (Controller <> Service <> Respository <> 외부API)
  • 특징
    • 요청/응답 형식(JSON 스키마)에 맞춰 설계
    • 비즈니스 로직 없이 데이터 전송(getter/setter)에만 초점을 맞추며, View(화면)의 요구사항에 맞게 데이터를 가공
    • 필드 + getter/ setter > 데이터를 담는 단순한 구조

✅ 핵심 포인트
필드: 요청/응답에서 필요한 데이터만.
기본 생성자: JSON 역직렬화(Jackson) 시 필수.
Getter/Setter: 값 읽기/쓰기 가능하게.
비즈니스 로직 없음: 계산, 검증은 Service나 Domain에서.


public class FruitCreateRequest {
    // 1. 전달할 데이터 필드
    private String name;
    private String warehousingDate; // 문자열로 받는 경우 (JSON에서 LocalDate 변환 가능)
    private long price;

    // 2. 기본 생성자 (Jackson 역직렬화용)
    public FruitCreateRequest() {
    }

    // 3. 모든 필드를 초기화하는 생성자
    public FruitCreateRequest(String name, String warehousingDate, long price) {
        this.name = name;
        this.warehousingDate = warehousingDate;
        this.price = price;
    }

    // 4. Getter (JSON → 객체 변환 후 값 읽기)
    public String getName() {
        return name;
    }

    public String getWarehousingDate() {
        return warehousingDate;
    }

    public long getPrice() {
        return price;
    }

    // 5. Setter (필요 시)
       public void setName(String name) {
        this.name = name;
    }

    public void setWarehousingDate(String warehousingDate) {
        this.warehousingDate = warehousingDate;
    }

    public void setPrice(long price) {
        this.price = price;
    }

Domain (= Entity)

  • 목적 : 도메인 모델은 애플리케이션의 핵심 비즈니스 개념을 표현하는 객체 > "우리 서비스가 다루는 진짜 개념을 코드로 옮긴 것”
  • 특징
    • 비즈니스 규칙을 담음 (예: Fruit는 가격이 0보다 커야 한다, 입고일은 미래일 수 없다.)
    • 행동(메서드)을 가질 수 있음
    • 외부 형식(JSON, DB 스키마)에 종속되지 않음

import java.time.LocalDate;

public class Fruit {
    private final String name;
    private final LocalDate warehousingDate;
    private final long price;

    public Fruit(String name, LocalDate warehousingDate, long price) {
        // 비즈니스 규칙 검증
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Fruit name cannot be empty");
        }
        if (warehousingDate == null) {
            throw new IllegalArgumentException("Warehousing date is required");
        }
        if (warehousingDate.isAfter(LocalDate.now())) {
            throw new IllegalArgumentException("Warehousing date cannot be in the future");
        }
        if (price <= 0) {
            throw new IllegalArgumentException("Price must be greater than zero");
        }

        this.name = name;
        this.warehousingDate = warehousingDate;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }

    public long getPrice() {
        return price;
    }

    // 도메인 행동 예시: 할인 적용
    public Fruit applyDiscount(int percent) {
        long discountedPrice = price - (price * percent / 100);
        return new Fruit(name, warehousingDate, Math.max(discountedPrice, 1));
       }

✅ Domain vs DTO 차이

0개의 댓글