Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ docker compose -p kitchenpos up -d
- 메뉴 그룹을 등록할 수 있다.
- 메뉴 그룹의 이름이 올바르지 않으면 등록할 수 없다.
- 메뉴 그룹의 이름은 비워 둘 수 없다.
- 메뉴 그룹의 이름에는 비속어가 포함될 수 없다.
Copy link

Choose a reason for hiding this comment

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

지속적으로 요구사항 수정 👍 👍
요구사항에 변경됨에 따라 모델링도 수정해보는 것은 어떤가요?

Copy link

Choose a reason for hiding this comment

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

미션 진행하시면서 지속적으로 모델링 업데이트도 부탁드려요
지금까지 미션 진행하시면서 도메인 지식이 많이 쌓이셨을 것 같은데요~
구현하신 코드와 모델링 싱크 확인 부탁드려요

- 메뉴 그룹의 목록을 조회할 수 있다.

### 메뉴
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/kitchenpos/common/annotation/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package kitchenpos.common.annotation;

import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Validator {

@AliasFor(annotation = Component.class)
String value() default "";

}
33 changes: 33 additions & 0 deletions src/main/java/kitchenpos/common/domain/AggregateRoot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package kitchenpos.common.domain;

import org.springframework.data.domain.AfterDomainEventPublication;
import org.springframework.data.domain.DomainEvents;

import javax.persistence.Transient;
import java.util.ArrayList;
import java.util.List;

public interface AggregateRoot {
Copy link

Choose a reason for hiding this comment

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

애그리거트 루트를 직접 인터페이스를 통해 이벤트 발행까지 만들어주셨네요 👍 👍
Spring 에서 AbstractAggregateRoot 를 제공해주고 있는 것이 있는데, 이것도 같이 확인해보시면 좋을 것 같아요


@Transient
ThreadLocal<List<Object>> threadLocal = ThreadLocal.withInitial(ArrayList::new);

default Object register(Object event) {
Copy link

Choose a reason for hiding this comment

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

인터페이스의 default 메서드가 추가된 배경은 무엇일까요?
추상클래스 대신 인터페이스를 사용하신 이유가 있으실까요? 🤔

if (event == null) {
return event;
}
threadLocal.get().add(event);
return event;
}

@AfterDomainEventPublication
default void clear() {
threadLocal.get().clear();
}

@DomainEvents
default List<Object> domainEvents() {
return new ArrayList<>(threadLocal.get());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

public enum KitchenPosExceptionType implements KitchenPosThrowable {

BAD_REQUEST( "잘못된 요청입니다."),
METHOD_NOT_ALLOWED( "허용되지 않은 기능입니다."),
NOT_FOUND( "찾을 수 없습니다."),
INTERNAL_SERVER_ERROR( "서버 내부 에러입니다."),
BAD_REQUEST("잘못된 요청입니다."),
METHOD_NOT_ALLOWED("허용되지 않은 기능입니다."),
NOT_FOUND("찾을 수 없습니다."),
INTERNAL_SERVER_ERROR("서버 내부 에러입니다."),
;

private final String message;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/kitchenpos/common/infra/DefaultPurgomalum.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public DefaultPurgomalum(final RestTemplateBuilder restTemplateBuilder) {
@Override
public boolean containsProfanity(final String text) {
final URI url = UriComponentsBuilder.fromUriString("https://www.purgomalum.com/service/containsprofanity")
.queryParam("text", text)
.build()
.toUri();
.queryParam("text", text)
.build()
.toUri();
return Boolean.parseBoolean(restTemplate.getForObject(url, String.class));
}
}
19 changes: 19 additions & 0 deletions src/main/java/kitchenpos/common/util/CollectionUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kitchenpos.common.util;

import kitchenpos.common.exception.KitchenPosException;
import org.springframework.lang.Nullable;

import java.util.Collection;

public class CollectionUtils {

private CollectionUtils() {
}

public static void requireNonEmpty(@Nullable Collection<?> collection, KitchenPosException exception) {
if (collection == null || collection.isEmpty()) {
throw exception;
}
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kitchenpos.common;
package kitchenpos.common.util;

import java.math.BigDecimal;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/kitchenpos/common/values/Name.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private static void validate(String value, Purgomalum purgomalum) {
String message = String.format("이름이 %s 이므로", value);
throw new KitchenPosException(message, KitchenPosExceptionType.BAD_REQUEST);
}
if(purgomalum.containsProfanity(value)) {
if (purgomalum.containsProfanity(value)) {
String message = String.format("이름=%s 에 비속어가 포함되어 있으므로", value);
throw new KitchenPosException(message, KitchenPosExceptionType.BAD_REQUEST);
}
Expand Down
32 changes: 23 additions & 9 deletions src/main/java/kitchenpos/common/values/Price.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

import kitchenpos.common.exception.KitchenPosException;
import kitchenpos.common.exception.KitchenPosExceptionType;
import kitchenpos.common.util.ComparisonUtils;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;

import static java.math.BigDecimal.ZERO;
import static kitchenpos.common.ComparisonUtils.lessThan;
import static kitchenpos.common.util.ComparisonUtils.lessThan;

@Embeddable
public class Price {

public static final Price ZERO = new Price(BigDecimal.ZERO);

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

Expand All @@ -25,13 +26,14 @@ protected Price() {
public Price(final Long value) {
this(BigDecimal.valueOf(value));
}

public Price(final BigDecimal value) {
validate(value);
this.value = value;
}

private static void validate(BigDecimal value) {
if (value == null || lessThan(value, ZERO)) {
if (value == null || lessThan(value, BigDecimal.ZERO)) {
String message = String.format("가격이 %s 이므로", value);
throw new KitchenPosException(message, KitchenPosExceptionType.BAD_REQUEST);
}
Expand All @@ -42,7 +44,7 @@ public BigDecimal getValue() {
}

public boolean equalValue(BigDecimal value) {
return this.value.equals(value);
return ComparisonUtils.isEqual(this.value, value);
}

@Override
Expand All @@ -58,11 +60,23 @@ public int hashCode() {
return Objects.hash(value);
}

public BigDecimal multiply(BigDecimal bigDecimal) {
return value.multiply(bigDecimal);
public Price add(Price price) {
BigDecimal result = value.add(price.value);
return new Price(result);
}

public Price multiply(long number) {
return multiply(BigDecimal.valueOf(number));
}
public BigDecimal multiply(long bigDecimal) {
return value.multiply(BigDecimal.valueOf(bigDecimal));

public Price multiply(BigDecimal number) {
BigDecimal result = value.multiply(number);
return new Price(result);
}


public boolean isGreaterThan(Price price) {
return ComparisonUtils.greaterThan(value, price.value);
}

}
47 changes: 47 additions & 0 deletions src/main/java/kitchenpos/common/values/Quantity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package kitchenpos.common.values;

import kitchenpos.common.exception.KitchenPosException;
import kitchenpos.common.exception.KitchenPosExceptionType;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.util.Objects;

@Embeddable
public class Quantity {

@Column(name = "quantity", nullable = false)
private Long value;

protected Quantity() {
}

public Quantity(final Long value) {
if (value < 0) {
String message = String.format("수량이 %s 이므로", value);
throw new KitchenPosException(message, KitchenPosExceptionType.BAD_REQUEST);
}
this.value = value;
}

public Long getValue() {
return value;
}

public boolean equalValue(Long value) {
return this.value.equals(value);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Quantity quantity = (Quantity) o;
return Objects.equals(value, quantity.value);
}

@Override
public int hashCode() {
return Objects.hash(value);
}
}
34 changes: 17 additions & 17 deletions src/main/java/kitchenpos/eatinorders/application/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public class OrderService {
private final KitchenridersClient kitchenridersClient;

public OrderService(
final OrderRepository orderRepository,
final MenuRepository menuRepository,
final OrderTableRepository orderTableRepository,
final KitchenridersClient kitchenridersClient
final OrderRepository orderRepository,
final MenuRepository menuRepository,
final OrderTableRepository orderTableRepository,
final KitchenridersClient kitchenridersClient
) {
this.orderRepository = orderRepository;
this.menuRepository = menuRepository;
Expand All @@ -42,9 +42,9 @@ public Order create(final Order request) {
throw new IllegalArgumentException();
}
final List<Menu> menus = menuRepository.findAllByIdIn(
orderLineItemRequests.stream()
.map(OrderLineItem::getMenuId)
.collect(Collectors.toList())
orderLineItemRequests.stream()
.map(OrderLineItem::getMenuId)
.collect(Collectors.toList())
);
if (menus.size() != orderLineItemRequests.size()) {
throw new IllegalArgumentException();
Expand All @@ -58,11 +58,11 @@ public Order create(final Order request) {
}
}
final Menu menu = menuRepository.findById(orderLineItemRequest.getMenuId())
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (!menu.isDisplayed()) {
throw new IllegalStateException();
}
if (menu.getPrice().compareTo(orderLineItemRequest.getPrice()) != 0) {
if (!menu.getPrice().equalValue(orderLineItemRequest.getPrice())) {
throw new IllegalArgumentException();
}
final OrderLineItem orderLineItem = new OrderLineItem();
Expand All @@ -85,7 +85,7 @@ public Order create(final Order request) {
}
if (type == OrderType.EAT_IN) {
final OrderTable orderTable = orderTableRepository.findById(request.getOrderTableId())
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (!orderTable.isOccupied()) {
throw new IllegalStateException();
}
Expand All @@ -97,16 +97,16 @@ public Order create(final Order request) {
@Transactional
public Order accept(final UUID orderId) {
final Order order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (order.getStatus() != OrderStatus.WAITING) {
throw new IllegalStateException();
}
if (order.getType() == OrderType.DELIVERY) {
BigDecimal sum = BigDecimal.ZERO;
for (final OrderLineItem orderLineItem : order.getOrderLineItems()) {
sum = orderLineItem.getMenu()
.getPrice()
.multiply(BigDecimal.valueOf(orderLineItem.getQuantity()));
.getPrice()
.multiply(BigDecimal.valueOf(orderLineItem.getQuantity())).getValue();
}
kitchenridersClient.requestDelivery(orderId, sum, order.getDeliveryAddress());
}
Expand All @@ -117,7 +117,7 @@ public Order accept(final UUID orderId) {
@Transactional
public Order serve(final UUID orderId) {
final Order order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (order.getStatus() != OrderStatus.ACCEPTED) {
throw new IllegalStateException();
}
Expand All @@ -128,7 +128,7 @@ public Order serve(final UUID orderId) {
@Transactional
public Order startDelivery(final UUID orderId) {
final Order order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (order.getType() != OrderType.DELIVERY) {
throw new IllegalStateException();
}
Expand All @@ -142,7 +142,7 @@ public Order startDelivery(final UUID orderId) {
@Transactional
public Order completeDelivery(final UUID orderId) {
final Order order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (order.getStatus() != OrderStatus.DELIVERING) {
throw new IllegalStateException();
}
Expand All @@ -153,7 +153,7 @@ public Order completeDelivery(final UUID orderId) {
@Transactional
public Order complete(final UUID orderId) {
final Order order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
final OrderType type = order.getType();
final OrderStatus status = order.getStatus();
if (type == OrderType.DELIVERY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ public OrderTable create(final OrderTable request) {
@Transactional
public OrderTable sit(final UUID orderTableId) {
final OrderTable orderTable = orderTableRepository.findById(orderTableId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
orderTable.setOccupied(true);
return orderTable;
}

@Transactional
public OrderTable clear(final UUID orderTableId) {
final OrderTable orderTable = orderTableRepository.findById(orderTableId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) {
throw new IllegalStateException();
}
Expand All @@ -63,7 +63,7 @@ public OrderTable changeNumberOfGuests(final UUID orderTableId, final OrderTable
throw new IllegalArgumentException();
}
final OrderTable orderTable = orderTableRepository.findById(orderTableId)
.orElseThrow(NoSuchElementException::new);
.orElseThrow(NoSuchElementException::new);
if (!orderTable.isOccupied()) {
throw new IllegalStateException();
}
Expand Down
Loading