-
Notifications
You must be signed in to change notification settings - Fork 177
Step1 : 1단계 - 리팩터링(상품) #331
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: wotjd4305
Are you sure you want to change the base?
Changes from 5 commits
909d47a
4097bfb
46a29e4
736f7ea
8a5adb0
e67128c
2c80661
4cf6dd0
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 |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package kitchenpos.menus.tobe.domain; | ||
|
|
||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Entity; | ||
| import jakarta.persistence.ForeignKey; | ||
| import jakarta.persistence.GeneratedValue; | ||
| import jakarta.persistence.GenerationType; | ||
| import jakarta.persistence.Id; | ||
| import jakarta.persistence.JoinColumn; | ||
| import jakarta.persistence.ManyToOne; | ||
| import jakarta.persistence.Table; | ||
| import jakarta.persistence.Transient; | ||
| import kitchenpos.products.tobe.domain.Product; | ||
|
|
||
| import java.util.UUID; | ||
|
|
||
| @Table(name = "menu_product") | ||
| @Entity | ||
| public class MenuProduct { | ||
| @Column(name = "seq") | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Id | ||
| private Long seq; | ||
|
|
||
| @ManyToOne(optional = false) | ||
| @JoinColumn( | ||
| name = "product_id", | ||
| columnDefinition = "binary(16)", | ||
| foreignKey = @ForeignKey(name = "fk_menu_product_to_product") | ||
| ) | ||
| private Product product; | ||
|
|
||
| @Column(name = "quantity", nullable = false) | ||
| private long quantity; | ||
|
|
||
| @Transient | ||
| private UUID productId; | ||
|
|
||
| public MenuProduct() { | ||
| } | ||
|
|
||
| public Long getSeq() { | ||
| return seq; | ||
| } | ||
|
|
||
| public void setSeq(final Long seq) { | ||
| this.seq = seq; | ||
| } | ||
|
|
||
| public Product getProduct() { | ||
| return product; | ||
| } | ||
|
|
||
| public void setProduct(final Product product) { | ||
| this.product = product; | ||
| } | ||
|
|
||
| public long getQuantity() { | ||
| return quantity; | ||
| } | ||
|
|
||
| public void setQuantity(final long quantity) { | ||
| this.quantity = quantity; | ||
| } | ||
|
|
||
| public UUID getProductId() { | ||
| return productId; | ||
| } | ||
|
|
||
| public void setProductId(final UUID productId) { | ||
| this.productId = productId; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| package kitchenpos.products.tobe.application; | ||
|
|
||
| import kitchenpos.menus.domain.Menu; | ||
| import kitchenpos.menus.domain.MenuProduct; | ||
| import kitchenpos.menus.domain.MenuRepository; | ||
| import kitchenpos.products.tobe.domain.Product; | ||
| import kitchenpos.products.tobe.domain.ProductName; | ||
| import kitchenpos.products.tobe.domain.ProductRepository; | ||
| import kitchenpos.products.infra.PurgomalumClient; | ||
| import kitchenpos.products.tobe.domain.Price; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.List; | ||
| import java.util.NoSuchElementException; | ||
| import java.util.UUID; | ||
|
|
||
| @Service | ||
| public class ProductService { | ||
| private final ProductRepository productRepository; | ||
| private final MenuRepository menuRepository; | ||
| private final PurgomalumClient purgomalumClient; | ||
|
|
||
| public ProductService( | ||
| final ProductRepository productRepository, | ||
| final MenuRepository menuRepository, | ||
| final PurgomalumClient purgomalumClient | ||
| ) { | ||
| this.productRepository = productRepository; | ||
| this.menuRepository = menuRepository; | ||
| this.purgomalumClient = purgomalumClient; | ||
| } | ||
|
|
||
| @Transactional | ||
| public Product create(final Product request) { | ||
| final String name = request.getName().getName(); | ||
| final Price price = new Price(request.getPrice().getPrice()); | ||
| final ProductName productName = new ProductName(name, purgomalumClient); | ||
| final Product product = new Product(); | ||
| product.setId(UUID.randomUUID()); | ||
| product.setName(productName); | ||
| product.setPrice(price); | ||
| return productRepository.save(product); | ||
| } | ||
|
|
||
| @Transactional | ||
| public Product changePrice(final UUID productId, final Product request) { | ||
| final Price price = new Price(request.getPrice().getPrice()); | ||
| final Product product = productRepository.findById(productId) | ||
| .orElseThrow(NoSuchElementException::new); | ||
| product.setPrice(price); | ||
| final List<Menu> menus = menuRepository.findAllByProductId(productId); | ||
| for (final Menu menu : menus) { | ||
| 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) { | ||
| menu.setDisplayed(false); | ||
| } | ||
| } | ||
| return product; | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public List<Product> findAll() { | ||
| return productRepository.findAll(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package kitchenpos.products.tobe.domain; | ||
|
|
||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Embeddable; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.Objects; | ||
|
|
||
| @Embeddable | ||
| public class Price { | ||
|
|
||
| @Column(name = "price", nullable = false) | ||
| private BigDecimal price; | ||
|
|
||
| protected Price() { | ||
| } | ||
|
|
||
| public Price(Long price) { | ||
| if (Objects.isNull(price)) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| var tempPrice = BigDecimal.valueOf(price); | ||
| validate(tempPrice); | ||
| this.price = tempPrice; | ||
| } | ||
|
|
||
| public Price(BigDecimal price) { | ||
| validate(price); | ||
| this.price = price; | ||
| } | ||
|
|
||
| public void validate(BigDecimal price) { | ||
| if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
|
|
||
| public BigDecimal multiply(BigDecimal bigDecimal) { | ||
| return price.multiply(bigDecimal); | ||
| } | ||
|
|
||
| public BigDecimal getPrice() { | ||
| return price; | ||
| } | ||
|
|
||
| public void setPrice(BigDecimal price) { | ||
| this.price = price; | ||
| } | ||
|
||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
| Price price1 = (Price) o; | ||
| return Objects.equals(price, price1.price); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hashCode(price); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package kitchenpos.products.tobe.domain; | ||
|
|
||
| import jakarta.persistence.*; | ||
|
|
||
| import java.util.UUID; | ||
|
|
||
| @Table(name = "product") | ||
| @Entity | ||
| public class Product { | ||
| @Column(name = "id", columnDefinition = "binary(16)") | ||
| @Id | ||
| private UUID id; | ||
|
|
||
| @Embedded | ||
| private ProductName name; | ||
|
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. VO 사용 👍 |
||
|
|
||
| @Embedded | ||
| private Price price; | ||
|
|
||
| public Product() { | ||
| } | ||
|
|
||
| public UUID getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public void setId(final UUID id) { | ||
|
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. Setter를 의미있게 변경해보면 어떨까요?
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. Product의 ID만을 세팅하는 경우는 없고, 생성하기 위해서 이름, 가격을 주입 받고 있습니다! |
||
| this.id = id; | ||
| } | ||
|
|
||
| public ProductName getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public void setName(final ProductName name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public Price getPrice() { | ||
| return price; | ||
| } | ||
|
|
||
| public void setPrice(Price price) { | ||
| this.price = price; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package kitchenpos.products.tobe.domain; | ||
|
|
||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Embeddable; | ||
| import kitchenpos.products.infra.PurgomalumClient; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.Objects; | ||
|
|
||
| @Embeddable | ||
| public class ProductName { | ||
|
|
||
| @Column(name = "name", nullable = false) | ||
| private String name; | ||
|
|
||
| protected ProductName() { | ||
| } | ||
|
|
||
| public ProductName(String name, PurgomalumClient purgomalumClient) { | ||
| validate(name, purgomalumClient); | ||
| this.name = name; | ||
| } | ||
|
|
||
| public void validate(String name, PurgomalumClient purgomalumClient) { | ||
| if (Objects.isNull(name) || name.trim().isEmpty()) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
|
|
||
| if (purgomalumClient.containsProfanity(name)) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| this.name = name; | ||
| } | ||
|
Comment on lines
+19
to
+33
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. ProductName의 역할이 무엇인지 알 수 있겠네요~! 👍 |
||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| this.name = name; | ||
| } | ||
|
||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
| ProductName that = (ProductName) o; | ||
| return Objects.equals(name, that.name); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hashCode(name); | ||
| } | ||
|
Comment on lines
+39
to
+50
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. 꼭 필요한 선언이죠~! 👍 |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package kitchenpos.products.tobe.domain; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Optional; | ||
| import java.util.UUID; | ||
|
|
||
| public interface ProductRepository { | ||
| Product save(Product product); | ||
|
|
||
| Optional<Product> findById(UUID id); | ||
|
|
||
| List<Product> findAll(); | ||
|
|
||
| List<Product> findAllByIdIn(List<UUID> ids); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package kitchenpos.products.tobe.application; | ||
|
|
||
| import kitchenpos.products.tobe.domain.Product; | ||
| import kitchenpos.products.tobe.domain.ProductRepository; | ||
|
|
||
| import java.util.*; | ||
|
|
||
| public class InMemoryProductRepository implements ProductRepository { | ||
| private final Map<UUID, Product> products = new HashMap<>(); | ||
|
|
||
| @Override | ||
| public Product save(final Product product) { | ||
| products.put(product.getId(), product); | ||
| return product; | ||
| } | ||
|
|
||
| @Override | ||
| public Optional<Product> findById(final UUID id) { | ||
| return Optional.ofNullable(products.get(id)); | ||
| } | ||
|
|
||
| @Override | ||
| public List<Product> findAll() { | ||
| return new ArrayList<>(products.values()); | ||
| } | ||
|
|
||
| @Override | ||
| public List<Product> findAllByIdIn(final List<UUID> ids) { | ||
| return products.values() | ||
| .stream() | ||
| .filter(product -> ids.contains(product.getId())) | ||
| .toList(); | ||
| } | ||
| } |
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.
👍