Skip to content
Open
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,13 @@ docker compose -p kitchenpos up -d
- `Order`๋Š” ์ ‘์ˆ˜ ๋Œ€๊ธฐ โžœ ์ ‘์ˆ˜ โžœ ์„œ๋น™ โžœ ๊ณ„์‚ฐ ์™„๋ฃŒ ์ˆœ์„œ๋กœ ์ง„ํ–‰๋œ๋‹ค.
- `OrderLineItem`๋Š” ๊ฐ€๊ฒฉ๊ณผ ์ˆ˜๋Ÿ‰์„ ๊ฐ€์ง„๋‹ค.
- `OrderLineItem`์˜ ์ˆ˜๋Ÿ‰์€ 1๋ณด๋‹ค ์ปค์•ผ ํ•œ๋‹ค.


#### step1 ์š”๊ตฌ์‚ฌํ•ญ

- ํ‚ค์นœํฌ์Šค์˜ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ์šฉ์–ด ์‚ฌ์ „, ๋ชจ๋ธ๋ง์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํ’ˆ CONTEXT๋ฅผ ๋ฆฌํŒฉํ„ฐ๋งํ•œ๋‹ค.
- ์ƒํ’ˆ CONTEXT์˜ ๋„๋ฉ”์ธ ๊ณ„์ธต๋งŒ ๋จผ์ € ๊ตฌํ˜„ํ•œ๋‹ค.
- products ํŒจํ‚ค์ง€ ๋ฐ‘์— tobe.domain ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฑฐ๊ธฐ์„œ๋ถ€ํ„ฐ ๊ตฌํ˜„์„ ์‹œ์ž‘ํ•œ๋‹ค.
- ์šฉ์–ด ์‚ฌ์ „๊ณผ ๋ชจ๋ธ๋ง์ด ๋ถ€์ž์—ฐ์Šค๋Ÿฝ๊ฑฐ๋‚˜ ๋ถˆ์™„์ „ํ•˜๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์ง€์†์ ์œผ๋กœ ์ˆ˜์ •ํ•œ๋‹ค.
- ์ƒˆ๋กœ์šด ๋ชจ๋ธ์— ๋งž๊ฒŒ๋” ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ๋ชจ๋“ˆ์˜ ์ด๋ฆ„์„ ๋‹ค์‹œ ์ง€์œผ๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋งํ•œ๋‹ค.
- REPOSITORY ๊ตฌํ˜„ ์‹œ ์ž์‹ ์—๊ฒŒ ์ต์ˆ™ํ•˜๊ณ  ํŽธํ•œ ๊ฒƒ์„ ์„ ํƒํ•˜์—ฌ ์ง„ํ–‰ํ•œ๋‹ค.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ group = "camp.nextstep.edu"
version = "0.0.1-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/kitchenpos/menus/application/MenuService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import kitchenpos.menus.domain.MenuGroupRepository;
import kitchenpos.menus.domain.MenuProduct;
import kitchenpos.menus.domain.MenuRepository;
import kitchenpos.products.domain.Product;
import kitchenpos.products.domain.ProductRepository;
import kitchenpos.products.infra.PurgomalumClient;
import kitchenpos.products.asis.domain.Product;
import kitchenpos.products.asis.domain.ProductRepository;
import kitchenpos.products.asis.infra.PurgomalumClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/kitchenpos/menus/domain/MenuProduct.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import kitchenpos.products.domain.Product;
import kitchenpos.products.asis.domain.Product;

import java.util.UUID;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package kitchenpos.products.application;
package kitchenpos.products.asis.application;

import kitchenpos.menus.domain.Menu;
import kitchenpos.menus.domain.MenuProduct;
import kitchenpos.menus.domain.MenuRepository;
import kitchenpos.products.domain.Product;
import kitchenpos.products.domain.ProductRepository;
import kitchenpos.products.infra.PurgomalumClient;
import kitchenpos.products.asis.domain.Product;
import kitchenpos.products.asis.domain.ProductRepository;
import kitchenpos.products.asis.infra.PurgomalumClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.products.domain;
package kitchenpos.products.asis.domain;

import org.springframework.data.jpa.repository.JpaRepository;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.products.domain;
package kitchenpos.products.asis.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.products.domain;
package kitchenpos.products.asis.domain;

import java.util.List;
import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.products.infra;
package kitchenpos.products.asis.infra;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.products.infra;
package kitchenpos.products.asis.infra;

public interface PurgomalumClient {
boolean containsProfanity(String text);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package kitchenpos.products.tobe.application;

import java.math.BigDecimal;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
import kitchenpos.menus.domain.Menu;
import kitchenpos.menus.domain.MenuProduct;
import kitchenpos.menus.domain.MenuRepository;
import kitchenpos.products.tobe.application.dto.ProductCreateRequest;
import kitchenpos.products.tobe.application.dto.ProductPriceUpdateRequest;
import kitchenpos.products.tobe.application.dto.ProductResponse;
import kitchenpos.products.tobe.domain.Product;
import kitchenpos.products.tobe.domain.ProductRepository;
import kitchenpos.products.tobe.infra.PurgomalumClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ProductService {

private final ProductRepository jpaProductRepository;
private final MenuRepository menuRepository;
private final PurgomalumClient purgomalumClient;

public ProductService(
final ProductRepository productRepository,
final MenuRepository menuRepository,
final PurgomalumClient purgomalumClient
) {
this.jpaProductRepository = productRepository;
this.menuRepository = menuRepository;
this.purgomalumClient = purgomalumClient;
}

@Transactional
public ProductResponse create(ProductCreateRequest request) {
Product product = jpaProductRepository.save(Product.of(request.getName(), request.getPrice(), purgomalumClient));

return ProductResponse.toResponse(product);
}

@Transactional
public ProductResponse changePrice(UUID productId, ProductPriceUpdateRequest request) {

Product product = jpaProductRepository.findById(productId)
.orElseThrow(NoSuchElementException::new);
product.updatePrice(request.getPrice());

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);
}
}
Comment on lines +50 to +63
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProductService์˜ ๋ฉ”๋‰ด ๊ฐ€๊ฒฉ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•ด๋ณด๋ฉด ์–ด๋–จ๊นŒ์š”? :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋‹ค์Œ ๋‹จ๊ณ„์ธ ๋ฉ”๋‰ด ๋ฆฌํŽ™ํ„ฐ๋ง๋ถ€๋ถ„ ์—์„œ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ์ด ๋ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค!

return ProductResponse.toResponse(product);
}

@Transactional(readOnly = true)
public List<ProductResponse> findAll() {
return jpaProductRepository.findAll()
.stream()
.map(ProductResponse::toResponse)
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package kitchenpos.products.tobe.application.dto;

import java.math.BigDecimal;

public class ProductCreateRequest {
private final String name;
private final BigDecimal price;

public ProductCreateRequest(String name, BigDecimal price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}

public BigDecimal getPrice() {
return price;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kitchenpos.products.tobe.application.dto;

import java.math.BigDecimal;

public class ProductPriceUpdateRequest {
private final BigDecimal price;

public ProductPriceUpdateRequest(BigDecimal price) {
this.price = price;
}

public BigDecimal getPrice() {
return price;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package kitchenpos.products.tobe.application.dto;

import java.math.BigDecimal;
import java.util.UUID;
import kitchenpos.products.tobe.domain.Product;

public class ProductResponse {
private final UUID id;
private final String name;
private final BigDecimal price;

public ProductResponse(UUID id, String name, BigDecimal price) {
this.id = id;
this.name = name;
this.price = price;
}

public UUID getId() {
return id;
}

public String getName() {
return name;
}

public BigDecimal getPrice() {
return price;
}

public static ProductResponse toResponse(Product product) {
return new ProductResponse(product.getId(), product.getName(), product.getPrice());
}
}
56 changes: 56 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package kitchenpos.products.tobe.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

import java.math.BigDecimal;
import java.util.UUID;
import kitchenpos.products.tobe.infra.PurgomalumClient;

@Table(name = "product")
@Entity
public class Product {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Product์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๋น ์ง„ ๊ฒƒ ๊ฐ™์•„์š”!


@Column(name = "id", columnDefinition = "binary(16)")
@Id
private UUID id;

@Embedded
private ProductName name;

@Embedded
private ProductPrice price;

protected Product() {
}

private Product(ProductName name, ProductPrice price) {
this.id = UUID.randomUUID();
this.name = name;
this.price = price;
}

public static Product of(String name, BigDecimal price, PurgomalumClient purgomalumClient) {
return new Product(ProductName.from(name, purgomalumClient),
ProductPrice.from(price));
}

public UUID getId() {
return id;
}

public String getName() {
return name.getName();
}

public BigDecimal getPrice() {
return price.getPrice();
}

public void updatePrice(BigDecimal price) {
this.price = ProductPrice.from(price);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Service์—์„œ๋Š” changePrice, ๋„๋ฉ”์ธ์—์„œ๋Š” updatePrice๋ผ๊ณ  ํ‘œํ˜„ํ•ด์ฃผ์…จ๋Š”๋ฐ,
๋‘˜์„ ๋‹ค๋ฅด๊ฒŒ ํ‘œํ˜„ํ•œ ์˜๋„ ์žˆ์œผ์‹ค๊นŒ์š”? :)
๊ทธ๋ฆฌ๊ณ  ProductPrice ๋Œ€์‹  BigDecimal์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๊ฒŒ ํ•œ ์ด์œ ๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค ใ…Žใ…Ž

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request์˜ ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๋ฉด Product์—์„œ ๊ฐ’๊ฐ์ฒด์— ๋Œ€ํ•œ ์ƒ์„ฑ์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ๊ฐ€์ ธ๊ฐˆ๋ ค๊ณ  ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

}
34 changes: 34 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/ProductName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package kitchenpos.products.tobe.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import kitchenpos.products.tobe.infra.PurgomalumClient;

@Embeddable
public class ProductName {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vo๋กœ ์ •์˜ํ•ด๋ณด์…จ๊ตฐ์š” ๐Ÿ‘๐Ÿ‘


@Column(name = "name", nullable = false)
private String name;

protected ProductName() {
}

private ProductName(String name) {
this.name = name;
}

public static ProductName from(String name, PurgomalumClient purgomalumClient) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("์ƒํ’ˆ๋ช…์€ ํ•„์ˆ˜๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
}

if (purgomalumClient.containsProfanity(name)) {
throw new IllegalArgumentException("๋น„์†์–ด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.");
}
return new ProductName(name);
}

public String getName() {
return name;
}
}
33 changes: 33 additions & 0 deletions src/main/java/kitchenpos/products/tobe/domain/ProductPrice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package kitchenpos.products.tobe.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.math.BigDecimal;

@Embeddable
public class ProductPrice {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProductPrice pp1 = ProductPrice.from(new BigDecimal(500L))
ProductPrice pp2 = ProductPrice.from(new BigDecimal(500L))

pp1๊ณผ pp2๋Š” ๊ฐ™์„๊นŒ์š”? :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

euqals and hashcode๊ฐ€ ํ•„์š”ํ•˜๊ฒ ๊ตฐ์š”


@Column(name = "price", nullable = false)
private BigDecimal price;

protected ProductPrice() {}

private ProductPrice(BigDecimal price) {
this.price = price;
}

public static ProductPrice from(BigDecimal price) {
validate(price);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ƒ์„ฑ์ž์—์„œ ๊ฒ€์ฆํ•˜์‹œ์ง€ ์•Š์€ ์ด์œ ๊ฐ€ ๊ถ๊ธˆํ•ด์š”!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ฐ์ฒด ์ƒ์„ฑ์ž ์‹คํ–‰๋˜๊ธฐ ์ „์— ๊ฐ์ฒด๊ฐ€ ๊ฒ€์ฆ์ด ๋˜๋Š” ํ๋ฆ„์ด ๋งž์„๊ฑฐ ๊ฐ™์•„ ์ •์ ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ •์ ํŒฉํ„ฐ๋ฆฌ์—์„œ ๊ฒ€์ฆํ•˜์˜€์Šต๋‹ˆ๋‹ค.

return new ProductPrice(price);
}

private static void validate(BigDecimal price) {
if (price == null || price.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("๊ฐ€๊ฒฉ์€ 0 ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์˜ˆ์™ธ๋„ ์ปค์Šคํ…€ํ™” ํ•ด๋ณด๋ฉด ์–ด๋–จ๊นŒ์š”?

}
}

public BigDecimal getPrice() {
return price;
}
}
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);
}

Loading