정의

개념명 정의
도메인 - 어플리케이션의 핵심 비즈니스 로직을 반영하는 영역
- domain problem을 모델링한 객체로 이루어짐
- 주로 상태(state)와 행위(behavior)를 캡슐화
- 데이터 일관성을 위한 유효성검사(Validation) 포함
- Entity와 Value Object로 나뉘는 경우가 많다.
서비스 - 도메인 객체간의 협력을 조정, 도메인에 적합하지 않은 복합적 비즈니스 로직을 처리하는 계층
- 상태를 가지지 않음
- 트랜잭션 관리, 외부 시스템 호출, 도메인 간 상호작용을 책임짐
- 도메인의 비즈니스 규칙을 유지하면서 이를 효과적으로 활용하도록 돕는 조정자 역할

차이

두 개념은 역할과 책임의 관점에서 다름

개념명 특징
도메인 - 비즈니스의 핵심 규칙을 표현
- 주로 데이터를 보유하고, 해당 데이터와 관련된 동작(행위)을 정의
- 비즈니스 로직 중, 도메인 자체가 책임져야 하는 로직을 포함
  - ex. User - "사용자가 18세 이상이어야 회원가입 가능" 로직
서비스 - 도메인 객체 간의 협력을 조정하거나, 복합적 비즈니스 로직을 처리
- 도메인이 책임지기 애매한 비즈니스 로직(도메인 간 교차적 혹은 외부 시스템과 관련된 로직)
- 상태를 가지지 않고, 순수하게 로직만 포함하는 경우가 많음

서비스가 도메인인 이유

1. 서비스 또한 도메인 계층의 일부로 간주될 수 있기 때문
2. 도메인 모델(Domain Model) 패턴에서 서비스는 도메인 로직을 조정하고 결합하기 위해 설계된 도메인 서비스로 불림.
3. 하지만 정밀한 범위에서 서비스는 도메인 모델 그 자체라기 보다, 도메인 객체를 활용하는 조정자 역할
개념명 정의
도메인 로직 - 도메인 객체 내부에 정의된 로직
- 단일 엔티티에 국한된 비즈니스 규칙
public class User {
    private int age;
    public boolean isEligible() {
        return age >= 18;
    }
}

-------------

public class Product {
    private String name;
    private int stock;

    public void decreaseStock(int quantity) {
        if (quantity > stock) {
            throw new IllegalArgumentException("재고가 부족합니다.");
        }
        stock -= quantity;
    }
}
서비스 로직 - 여러 도메인 객체를 조합하거나,
- 외부 시스템과의 연계를 포함한 로직
- 상태를 가지지 않고, 특정 행위만 담당
@Service
public class UserService {
    public void registerUser(User user) {
        if (user.isEligible()) {
            // Repository를 이용해 저장
            userRepository.save(user);
        } else {
            throw new IllegalArgumentException(
            "사용자는 등록 자격이 없습니다.");
        }
    }
}

-------------------

@Service
public class OrderService {
    private final ProductRepository productRepository;
    private final OrderRepository orderRepository;

    public OrderService(ProductRepository productRepository, OrderRepository orderRepository) {
        this.productRepository = productRepository;
        this.orderRepository = orderRepository;
    }

    public void placeOrder(Long productId, int quantity) {
        Product product = productRepository.findById(productId)
                           .orElseThrow(() -> new IllegalArgumentException("상품을 찾을 수 없습니다."));

        product.decreaseStock(quantity); // 도메인 로직 호출
        productRepository.save(product);

        Order order = new Order(product, quantity);
        orderRepository.save(order);
    }
}

비고

1. DTO는 도메인과 완전히 다른 목적을 가진 객체임. Data Transfer Object, 말 그대로 데이터 전달에 사용. 주로 계층 간(Controller-Service-Client) 데이터 교환에 쓰이며, 상태와 행위를 포함하지 않고 순수하게 데이터를 담기만 함. 
  예) public class ProductResponseDto { private String name; private int stock; // 이하 생성자와 getter만 포함 }

레퍼런스

1. 멘토링 강의, 도서관, 코드 예시의 경우 ChatGPT

 

'개발지식 조각 > Java' 카테고리의 다른 글

JPA 더티 체킹과 @DynamicUpdate  (2) 2024.12.26
Thread 동기화  (0) 2024.12.03
일급 컬렉션(First-Class Collection)  (1) 2024.10.31
Static (변수/메서드/클래스)  (0) 2024.10.31
클린 코드의 정의  (0) 2024.10.31

+ Recent posts