인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

엔티티 비즈니스 로직 vs 서비스 비즈니스 로직

작성

·

298

·

수정됨

0

강의에서 DDD의 개념을 적용하시면서 엔티티에 비즈니스 로직을 넣으셨었는데요.

아직까진 DDD에 대한 개념이 완벽히 정립되지 않아 별도의 자료로 공부를 하고 있습니다.

공부하는 차원에서 서비스 계층에서의 비즈니스 로직 개발로 코드 리팩토링을 스스로 해보고 강의에 나오지 않았던 상품 서비스 테스트 코드 작성 결과 일단 통과가 나오긴 했습니다만... 잘 한 것인지 몰라서 코드 평가를 좀 받아보고 싶어 질문을 올리게 되었습니다.

테스트 코드 역시 각 계층별로 지켜야 하는 테스트 코드 원칙이 있으나 이 부분도 같이 공부하느라 제대로 적용해보기 아직 어려운 단계라 @SpringBootTest를 사용했습니다. 이 부분은 감안해주세요..!

 

또 다른 추가 질문이 있습니다. 강의에서 엔티티에 구현한 비즈니스 로직을 서비스 계층에 비즈니스 로직을 개발하는 방식으로 바꾸는 과정에서 엔티티를 직접 이용하는 것보다는 DTO를 만들어서 전달하는게 엔티티에 많은 변화를 가하지않는 유일한 방법일까요?

ItemService 코드

package spring.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import spring.project.domain.Item;
import spring.project.exception.NotEnoughStockException;
import spring.project.repository.ItemRepository;

import java.util.List;

@Service
@Transactional(readOnly = true)
public class ItemService {

	private final ItemRepository itemRepository;
	@Autowired
	public ItemService(ItemRepository itemRepository) {
		this.itemRepository = itemRepository;
	}

	@Transactional
	public Long saveItem(Item item, int quantity) {
		addStock(item, quantity);
		itemRepository.save(item);
		return item.getId();
	}

	private void addStock(Item item, int quantity) {
		item.setStockQuantity(item.getStockQuantity() + quantity);
		itemRepository.save(item);
	}

	@Transactional
	public void removeStock(Item item, int quantity) {
		int restStock = item.getStockQuantity() - quantity;
		if (restStock < 0) {
			throw new NotEnoughStockException("재고가 부족합니다.");
		}
		item.setStockQuantity(restStock);
		itemRepository.save(item);
	}

	public Item findOne(Long itemId) {
		return itemRepository.findOne(itemId);
	}

	public List<Item> findAll() {
		return itemRepository.findAll();
	}
}

ItemServiceTest 코드

package spring.project.service;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import spring.project.domain.Album;
import spring.project.domain.Book;
import spring.project.domain.Item;
import spring.project.repository.ItemRepository;

@SpringBootTest
class ItemServiceTest {

	@Autowired private ItemRepository itemRepository;
	@Autowired private ItemService itemService;

	@Test
	@DisplayName("상품 저장 시 상품 저장과 동시에 재고 수량이 증가해야 한다.")
	void save() {
		// given
		Book book = new Book();
		book.setAuthor("홍길동");

		// when
		Long id = itemService.saveItem(book, 3);

		// then
		Item item = itemRepository.findOne(id);
		Assertions.assertThat(item.getName()).isEqualTo(book.getName());
		Assertions.assertThat(item.getStockQuantity()).isEqualTo(3);
	}

	@Test
	@DisplayName("상품 주문이 들어가면 재고 수량에서 주문 수량만큼 차감이 되어야 한다.")
	void remove() {
		// given
		Album album = new Album();
		album.setName("영원");
		Long id = itemService.saveItem(album, 100);

		// when
		itemService.removeStock(album, 4);

		// then
		Item item = itemRepository.findOne(id);
		Assertions.assertThat(item.getStockQuantity()).isEqualTo(96);
	}
}

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. dhwiwnwnf님의 엔티티 내 비즈니스 로직과 서비스 계층에서 비즈니스 로직 처리에 대한 질문에 관해, 말씀해주신 상황을 기반으로 비슷한 맥락을 지닌 기존 질문들을 살펴보았습니다.

엔티티에 비즈니스 로직을 포함시키는 것이 DDD(Domain-Driven Design)의 한 방법론입니다. 이 접근법은 도메인이 비즈니스 로직의 주도권을 가지며 구현되는 것을 지향합니다. 물론, 서비스 계층에서 비즈니스 로직을 처리하는 전통적인 방법도 유효하며, 각각의 장단점이 있습니다.

비슷한 주제로 질문하셨던 다른 학습자의 질문에 답변된 내용을 참고할 만 한 내용이 있어 여기에 공유드립니다.

  • 비지니스 로직구현 Entity VS Service에서는 엔티티 내에 비즈니스 로직을 구현하는 방식과 서비스 계층에서 비즈니스 로직을 구현하는 방식의 차이점에 대한 설명이 있습니다. 도메인 주도 설계를 간략하게 설명하면서, 엔티티에 비즈니스 로직을 구현하는 이유와 그 장점에 대해 설명하고 있습니다.

  • entity에 비지니스 로직 관련 질문입니다.에서는 엔티티 내에 비즈니스 로직을 넣는 것과 관련하여, 그러한 방식이 왜 응집력을 높이는지에 대한 설명과 함께, 이에 대한 테스트 코드 작성에 관련된 질문을 다루고 있습니다. 이는 테스트 코드 작성이 어떻게 이루어져야 하는지에 대한 실질적인 사례로 참고가 될 수 있습니다.

dhwiwnwnf님께서 제시하신 ItemService와 테스트 코드에 관하여, 서비스 계층에서의 비즈니스 로직 처리가 올바르게 반영되었으며, 실제 비즈니스 요구사항을 충족시키는지에 대한 평가는 이론적인 지식과 함께 실제 업무에 적용해보며 얻을 수 있는 경험에서 더욱 명확해질 수 있습니다. 제공된 링크를 통해 엔티티와 서비스 계층에서의 비즈니스 로직 처리 방법의 이해를 심화하시길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기