-
Notifications
You must be signed in to change notification settings - Fork 177
2단계 - 리팩터링(메뉴) #169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: chr0m3
Are you sure you want to change the base?
2단계 - 리팩터링(메뉴) #169
Changes from 32 commits
bde7ea3
86b5760
4022276
8382a9b
a1644b4
b84cfe6
eb121a6
4e44a8f
2c52931
0146904
a968bc6
7ff9973
3621adb
5aab011
58bd527
0701e17
bf9bfb1
44adb96
2d16e74
218f580
c346395
26aa5e7
ac684f6
748ee71
96fe49a
f795b5c
2c7035e
a662282
a753755
86dc9e6
81afbbc
bd08ccb
71f200a
139c6f8
1c460a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,33 @@ | ||
| package kitchenpos.menu.application; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Objects; | ||
| import java.util.UUID; | ||
| import kitchenpos.menu.domain.MenuGroup; | ||
| import kitchenpos.menu.domain.MenuGroupRepository; | ||
| import kitchenpos.common.name.Name; | ||
| import kitchenpos.common.name.NameFactory; | ||
| import kitchenpos.menu.tobe.application.dto.CreateMenuGroupCommand; | ||
| import kitchenpos.menu.tobe.domain.entity.MenuGroup; | ||
| import kitchenpos.menu.tobe.domain.repository.MenuGroupRepository; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| public class MenuGroupService { | ||
|
|
||
| private final MenuGroupRepository menuGroupRepository; | ||
|
|
||
| public MenuGroupService(final MenuGroupRepository menuGroupRepository) { | ||
| private final NameFactory nameFactory; | ||
|
|
||
| @Autowired | ||
| public MenuGroupService(MenuGroupRepository menuGroupRepository, NameFactory nameFactory) { | ||
| this.menuGroupRepository = menuGroupRepository; | ||
| this.nameFactory = nameFactory; | ||
| } | ||
|
|
||
| @Transactional | ||
| public MenuGroup create(final MenuGroup request) { | ||
| final String name = request.getName(); | ||
| if (Objects.isNull(name) || name.isEmpty()) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final MenuGroup menuGroup = new MenuGroup(); | ||
| menuGroup.setId(UUID.randomUUID()); | ||
| menuGroup.setName(name); | ||
| public MenuGroup create(final CreateMenuGroupCommand request) { | ||
| final Name name = this.nameFactory.create(request.name); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이제 DTO를 받은 뒤 제대로 |
||
| final MenuGroup menuGroup = new MenuGroup(UUID.randomUUID(), name); | ||
| return menuGroupRepository.save(menuGroup); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,116 +1,94 @@ | ||
| package kitchenpos.menu.application; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.NoSuchElementException; | ||
| import java.util.Objects; | ||
| import java.util.UUID; | ||
| import java.util.stream.Collectors; | ||
| import kitchenpos.common.profanity.domain.ProfanityDetectService; | ||
| import kitchenpos.menu.domain.Menu; | ||
| import kitchenpos.menu.domain.MenuGroup; | ||
| import kitchenpos.menu.domain.MenuGroupRepository; | ||
| import kitchenpos.menu.domain.MenuProduct; | ||
| import kitchenpos.menu.domain.MenuRepository; | ||
| import kitchenpos.product.domain.Product; | ||
| import kitchenpos.product.domain.ProductRepository; | ||
| import kitchenpos.common.name.Name; | ||
| import kitchenpos.common.name.NameFactory; | ||
| import kitchenpos.common.price.Price; | ||
| import kitchenpos.menu.tobe.application.dto.ChangeMenuPriceCommand; | ||
| import kitchenpos.menu.tobe.application.dto.CreateMenuCommand; | ||
| import kitchenpos.menu.tobe.domain.entity.Menu; | ||
| import kitchenpos.menu.tobe.domain.entity.MenuGroup; | ||
| import kitchenpos.menu.tobe.domain.repository.MenuGroupRepository; | ||
| import kitchenpos.menu.tobe.domain.repository.MenuRepository; | ||
| import kitchenpos.menu.tobe.domain.vo.MenuProduct; | ||
| import kitchenpos.product.tobe.domain.entity.Product; | ||
| import kitchenpos.product.tobe.domain.repository.ProductRepository; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| public class MenuService { | ||
|
|
||
| private final MenuRepository menuRepository; | ||
|
|
||
| private final MenuGroupRepository menuGroupRepository; | ||
|
|
||
| private final ProductRepository productRepository; | ||
| private final ProfanityDetectService profanityDetectService; | ||
|
|
||
| private final NameFactory nameFactory; | ||
|
|
||
| @Autowired | ||
| public MenuService( | ||
| final MenuRepository menuRepository, | ||
| final MenuGroupRepository menuGroupRepository, | ||
| final ProductRepository productRepository, | ||
| final ProfanityDetectService profanityDetectService | ||
| final NameFactory nameFactory | ||
| ) { | ||
| this.menuRepository = menuRepository; | ||
| this.menuGroupRepository = menuGroupRepository; | ||
| this.productRepository = productRepository; | ||
| this.profanityDetectService = profanityDetectService; | ||
| this.nameFactory = nameFactory; | ||
| } | ||
|
|
||
| @Transactional | ||
| public Menu create(final Menu request) { | ||
| final BigDecimal price = request.getPrice(); | ||
| if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final MenuGroup menuGroup = menuGroupRepository.findById(request.getMenuGroupId()) | ||
| public Menu create(final CreateMenuCommand command) { | ||
| final Price price = new Price(command.price); | ||
| final MenuGroup menuGroup = menuGroupRepository.findById(command.menuGroupId) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동일한 Context에서 Root Aggregate간 결합을 허용할건지, 결합을 제거할건지 고민해보시는것도 권장 드립니다 😄 |
||
| .orElseThrow(NoSuchElementException::new); | ||
| final List<MenuProduct> menuProductRequests = request.getMenuProducts(); | ||
| final List<MenuProduct> menuProductRequests = command.menuProducts; | ||
| if (Objects.isNull(menuProductRequests) || menuProductRequests.isEmpty()) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final List<Product> products = productRepository.findAllByIdIn( | ||
| final Map<UUID, Price> productPrices = productRepository.findAllByIdIn( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Menu Application Layer에서 Product Context와의 결합을 제거할수 있는 방법을 고민해보세요 😄 |
||
| menuProductRequests.stream() | ||
| .map(MenuProduct::getProductId) | ||
| .collect(Collectors.toList()) | ||
| ); | ||
| if (products.size() != menuProductRequests.size()) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final List<MenuProduct> menuProducts = new ArrayList<>(); | ||
| BigDecimal sum = BigDecimal.ZERO; | ||
| for (final MenuProduct menuProductRequest : menuProductRequests) { | ||
| final long quantity = menuProductRequest.getQuantity(); | ||
| if (quantity < 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final Product product = productRepository.findById(menuProductRequest.getProductId()) | ||
| .orElseThrow(NoSuchElementException::new); | ||
| sum = sum.add( | ||
| product.getPrice() | ||
| .multiply(BigDecimal.valueOf(quantity)) | ||
| ); | ||
| final MenuProduct menuProduct = new MenuProduct(); | ||
| menuProduct.setProduct(product); | ||
| menuProduct.setQuantity(quantity); | ||
| menuProducts.add(menuProduct); | ||
| } | ||
| if (price.compareTo(sum) > 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final String name = request.getName(); | ||
| if (Objects.isNull(name) || profanityDetectService.profanityIn(name)) { | ||
| .map(menuProduct -> menuProduct.productId) | ||
| .collect(Collectors.toUnmodifiableList()) | ||
| ) | ||
| .stream() | ||
| .collect(Collectors.toMap(product -> product.id, Product::price)); | ||
| if (productPrices.size() != menuProductRequests.size()) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final Menu menu = new Menu(); | ||
| menu.setId(UUID.randomUUID()); | ||
| menu.setName(name); | ||
| menu.setPrice(price); | ||
| menu.setMenuGroup(menuGroup); | ||
| menu.setDisplayed(request.isDisplayed()); | ||
| menu.setMenuProducts(menuProducts); | ||
| final List<MenuProduct> menuProducts = menuProductRequests.stream() | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기존 구현에는 command에 포함된 가격(아마 클라이언트에서 요청한 가격)을 그대로 사용한다는 문제점이 있었습니다. |
||
| .map(menuProduct -> new MenuProduct( | ||
| menuProduct.productId, | ||
| productPrices.get(menuProduct.productId), | ||
| menuProduct.quantity | ||
| )) | ||
| .collect(Collectors.toUnmodifiableList()); | ||
| final Name name = this.nameFactory.create(command.name); | ||
| final Menu menu = new Menu( | ||
| UUID.randomUUID(), | ||
| name, | ||
| command.displayed, | ||
| price, | ||
| menuGroup, | ||
| menuProducts | ||
| ); | ||
| return menuRepository.save(menu); | ||
| } | ||
|
|
||
| @Transactional | ||
| public Menu changePrice(final UUID menuId, final Menu request) { | ||
| final BigDecimal price = request.getPrice(); | ||
| if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| final Menu menu = menuRepository.findById(menuId) | ||
| public Menu changePrice(final ChangeMenuPriceCommand command) { | ||
| final Price price = new Price(command.price); | ||
| final Menu menu = menuRepository.findById(command.id) | ||
| .orElseThrow(NoSuchElementException::new); | ||
| BigDecimal sum = BigDecimal.ZERO; | ||
| for (final MenuProduct menuProduct : menu.getMenuProducts()) { | ||
| sum = sum.add( | ||
| menuProduct.getProduct() | ||
| .getPrice() | ||
| .multiply(BigDecimal.valueOf(menuProduct.getQuantity())) | ||
| ); | ||
| } | ||
| if (price.compareTo(sum) > 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| menu.setPrice(price); | ||
| return menu; | ||
| } | ||
|
|
@@ -119,26 +97,15 @@ public Menu changePrice(final UUID menuId, final Menu request) { | |
| public Menu display(final UUID menuId) { | ||
| final Menu menu = menuRepository.findById(menuId) | ||
| .orElseThrow(NoSuchElementException::new); | ||
| BigDecimal sum = BigDecimal.ZERO; | ||
| for (final MenuProduct menuProduct : menu.getMenuProducts()) { | ||
| sum = sum.add( | ||
| menuProduct.getProduct() | ||
| .getPrice() | ||
| .multiply(BigDecimal.valueOf(menuProduct.getQuantity())) | ||
| ); | ||
| } | ||
| if (menu.getPrice().compareTo(sum) > 0) { | ||
| throw new IllegalStateException(); | ||
| } | ||
| menu.setDisplayed(true); | ||
| menu.display(); | ||
| return menu; | ||
| } | ||
|
|
||
| @Transactional | ||
| public Menu hide(final UUID menuId) { | ||
| final Menu menu = menuRepository.findById(menuId) | ||
| .orElseThrow(NoSuchElementException::new); | ||
| menu.setDisplayed(false); | ||
| menu.hide(); | ||
| return menu; | ||
| } | ||
|
|
||
|
|
||
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
도메인 모델을 그대로 받는 대신 요청하는 행위에 맞는 DTO를 도입해야 할 필요성이 느껴져 DTO를 추가했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DTO 도입 좋습니다 ㅎㅎ 😄