Skip to content
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

[김대겸] Step3 PR #735

Merged
merged 19 commits into from Dec 20, 2022
Merged

[김대겸] Step3 PR #735

merged 19 commits into from Dec 20, 2022

Conversation

Gyeom
Copy link

@Gyeom Gyeom commented Dec 18, 2022

안녕하세요 리뷰어님,

3단계 의존성 리팩터링 리뷰요청드립니다.

  1. 패키지 분리 (Lifecycle이 같은 도메인들은 같은 Aggregate)
  2. 서로 다른 Aggregate의 엔티티간의 단방향 참조를 할 수 있도록 간접참조 활용
  3. 비즈니스 로직을 보다 명확하고 쉽게 관리할 수 있도록 Validator를 활용한 절차지향 적용
  4. Order <-> OrderTable 간의 양방향 참조 문제를 해결하기 위해 인터페이스 및 구현체 활용 (DIP 원칙 적용)

이번 미션은 위에 작성한 내용을 중심으로 개발하였습니다.

이번 리뷰도 잘 부탁드립니다 🙏 🙏 🙏

Copy link
Member

@limwoobin limwoobin left a comment

Choose a reason for hiding this comment

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

안녕하세요 대겸님
3단계 반영 잘 해주셧습니다 ㅎㅎ

몇가지 고민해보면 좋을것같은 부분에 대해 코멘트를 남겨드렸습니다.
확인해보시고 다시 요청부탁드립니다!


menuValidator.validateCreateMenu(request, menuProducts);
Copy link
Member

Choose a reason for hiding this comment

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

validator를 메소드 맨 앞에서 처리하는건 어떨까요??

Copy link
Author

Choose a reason for hiding this comment

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

그게 더 나을 것 같네요~! validator 를 앞에서 처리하도록 수정하겠습니다ㅎㅎ

Comment on lines 32 to 33
final ProductRepository productRepository,
final MenuValidator menuValidator
Copy link
Member

Choose a reason for hiding this comment

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

productRepository도 MenuValidator에서 직접 의존하는건 어떨까요??
MenuValidator를 별도로 만드셧는데 해당 서비스코드에 있는 validate 로직은
이동시켜도 좋을것같습니다!

Copy link
Author

Choose a reason for hiding this comment

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

그렇게되면 menuservice 는 정말 menu도메인에 대해서만 의존할 수 있겠네요~!ㅎㅎ

Comment on lines 11 to 40
@Component
public class MenuValidator {
private final MenuGroupRepository menuGroupRepository;

public MenuValidator(MenuGroupRepository menuGroupRepository) {
this.menuGroupRepository = menuGroupRepository;
}

public void validateCreateMenu(MenuRequest menuRequest, MenuProducts menuProducts) {
validateMenuGroup(menuRequest.getMenuGroupId());
validateMenuProducts(menuRequest, menuProducts);
}

private void validateMenuGroup(Long menuGroupId) {
if (!menuGroupRepository.existsById(menuGroupId)) {
throw new IllegalArgumentException(INVALID_MENU_GROUP.getMessage());
}
}

private void validateMenuProducts(MenuRequest menuRequest, MenuProducts menuProducts) {
if (menuRequest.getMenuProductsRequest().size() != menuProducts.value().size()) {
throw new IllegalArgumentException(INVALID_MENU_PRODUCT.getMessage());
}

Price price = Price.from(menuRequest.getPrice());
if (price.compareTo(menuProducts.totalPrice()) > 0) {
throw new IllegalArgumentException(MENU_PRICE_LESS_THAN_SUM_OF_PRICE.getMessage());
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

validator로 잘 분리해주셨네요 ㅎㅎ 좋습니다
굳이 필수로 적용하실 필요는 없지만 해당 validator를 SRP, OCP를 준수해 별도의 validator로 분리해보는것에 대해
고민해보셔도 좋을것같아요
그리고 해당 validator들을 관리하는 별도의 객체를 생성하는 방법으로 풀어보면 보다 확장에 용이할 수 있을것같기도 하네요 :)

@@ -1,4 +1,4 @@
package kitchenpos.domain;
package kitchenpos.menugroup.domain;
Copy link
Member

Choose a reason for hiding this comment

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

해당 엔티티에서는 기본생성자의 접근제어자가 public이네요
protected로 제한해서 사용하면 무분별한 객체생성을 막을수 있을것같아요 ㅎㅎ
추가로 jpa에서 기본생성자를 private으로 사용했을때는 어떤 문제점이 있을지에 대해서도 같이 알아보시면 좋을것같네요!

Copy link
Author

Choose a reason for hiding this comment

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

public으로 되어 있는 엔티티가 꽤많네요 😢 수정하도록 하겠습니다~ ㅎㅎ

jpa가 프록시를 사용할 때 jpa hibernate가 객체를 강제로 생성해야되는데, 접근제한자가 private일 경우 생성을 못해서 예외가 발생하는 것으로 알고 있습니다~!ㅎㅎ

Long orderTableId = request.getOrderTableId();
OrderTable orderTable = orderTableRepository.findById(orderTableId)
.orElseThrow(() -> new IllegalArgumentException(String.format(ErrorMessage.NOT_FOUND_ORDER_TABLE.getMessage(), orderTableId)));
orderValidator.validate(request);
Copy link
Member

Choose a reason for hiding this comment

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

validateOrderLineItems 메소드는 orderValidator로 위임 안하신 이유가 있나요??

Copy link
Author

Choose a reason for hiding this comment

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

누락된것 같네요 ㅠㅠ 죄송스럽네요........ 😢

package kitchenpos.domain;
package kitchenpos.order.domain;

import kitchenpos.common.domain.Quantity;
Copy link
Member

Choose a reason for hiding this comment

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

메뉴의 이름과 가격이 변경되면 주문 항목도 함께 변경된다. 메뉴 정보가 변경되더라도 주문 항목이 변경되지 않게 구현한다. 와 같은 요구사항이 있습니다.
해당 요구사항이 충족되지 않은걸로 보이네요 :)

Copy link
Author

@Gyeom Gyeom Dec 20, 2022

Choose a reason for hiding this comment

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

요구사항을 빠뜨렸군요 ㅠㅠㅠㅠㅠㅠ
OrderLineItem에 menuName과 price칼럼을 추가하여 요구사항에 충족하도록 수정하겠습니다~!

Comment on lines +22 to +23
private final OrderRepository orderRepository;
private final OrderValidator orderValidator;
Copy link
Member

Choose a reason for hiding this comment

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

Order < -> OrderTable 양방향 의존관계를 맺고있네요
어떻게 의존관계를 끊으면 좋을지 고민해보심 좋을것같아요

Copy link
Member

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.

Order < -> OrderTable 양방향 의존관계를 맺고있네요

인터페이스 및 구현체(Validator, ValidatorImpl) 활용하여 DIP 원칙을 적용하여
Order <-> OrderTable 간의 양방향 참조 문제를 해결했다고 생각했는데,, 제가 이해하지 못한 내용이 있을까요...?

Copy link
Author

@Gyeom Gyeom Dec 20, 2022

Choose a reason for hiding this comment

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

추가로 패키지구조가 엔티티단위로 모두 나누어져 있네요 ㅎㅎ
별도의 이유가 있으시면 코멘트로 남겨주심 좋을것같아요
한편으론 같은 성격이라면 패키지를 합치는것도 고민해봐주시면 좋겟습니다 :)

패키지 구조의 경우 Aggregate 단위로 나눴습니다. Aggregate의 기준은 Lifecycle이 같은 도메인들끼리 그룹핑했습니다 :)

Copy link
Member

Choose a reason for hiding this comment

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

refactor(OrderValidator): Order, OrderTable 양방향 의존성 제거를 위한 DIP 적용(abbc0af)
리뷰할때 해당커밋이 없는버전으로 리뷰했던것같았는데 뭔가 혼선이 있었나보네요!
말씀하신대로 인터페이스 이용해 의존성 잘 끊어내주신게 맞네요 👍

package kitchenpos.menu.domain;

import kitchenpos.common.domain.Price;
import kitchenpos.product.domain.Product;
Copy link
Member

Choose a reason for hiding this comment

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

여기에선 Product를 직접참조방식으로 유지하셧네요 ㅎㅎ
혹시 직접참조방식을 유지하신 이유가 있을까요??
잘못되었다는건 아니고 의견이 궁금해서 여쭤봅니다!

Copy link
Author

Choose a reason for hiding this comment

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

관계가 단방향(MenuProduct -> Product)이라고 생각되었고, 앞으로도 양방향으로 바뀔일은 없다고 판단하여 직접참조방식을 유지했습니다 :)

Copy link
Member

Choose a reason for hiding this comment

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

양방향.단방향에 대한 질문은 아니었고
라이프 사이클관점에선 두 객체가 다름에도 id로 참조하지 않고 직접참조(객체참조)로 작성하신 이유가 궁금했습니다 ㅎㅎ
정답은 없는문제이기에 라이프사이클이 굳이 같지않더라도 빈번하게 같이 사용된다면 전 직접참조도 괜찮다고 생각들긴 하네요!

@Gyeom
Copy link
Author

Gyeom commented Dec 20, 2022

리뷰어님, 피드백 반영하여 리뷰 요청드립니다~!

저번 리뷰요청 때, 실수를 많이해서 죄송스럽네요 ㅠㅠ

이번 리뷰도 잘 부탁드립니다 :)

감사합니다.

Comment on lines +16 to +20
private Long menuId;
private String menuName;
@Embedded
@AttributeOverride(name = "price", column = @Column(name = "menu_price"))
private Price menuPrice;
Copy link
Member

Choose a reason for hiding this comment

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

피드백 잘 반영해주셨네요 ㅎㅎ
menuId, menuName, menuPrice 에 대해 일급컬렉션으로 묶는게
보다 명시적이지 않을까 싶습니다!

Copy link
Author

Choose a reason for hiding this comment

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

그러면 보다 쉽게 관리할 수 있겠네요~~!ㅎㅎ 수정하도록 하겠습니다

그런데 혹시 해당 경우에도 일급컬렉션이라고 지칭하나요~~?
저는 Collection들을 한번 래핑한 컬렉션정도로 생각하고 있었는데 궁금합니다~

Copy link
Member

Choose a reason for hiding this comment

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

@Gyeom 제가 잘못말씀드렸네요 ㅎㅎ
일급컬렉션이아닌 객체로 래핑하는걸 의도해서 말씀드린게 맞습니다!

Comment on lines +22 to +23
private final OrderRepository orderRepository;
private final OrderValidator orderValidator;
Copy link
Member

Choose a reason for hiding this comment

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

refactor(OrderValidator): Order, OrderTable 양방향 의존성 제거를 위한 DIP 적용(abbc0af)
리뷰할때 해당커밋이 없는버전으로 리뷰했던것같았는데 뭔가 혼선이 있었나보네요!
말씀하신대로 인터페이스 이용해 의존성 잘 끊어내주신게 맞네요 👍

Copy link
Member

@limwoobin limwoobin left a comment

Choose a reason for hiding this comment

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

대겸님 3단계 피드백 잘 반영해주셨습니다 👍👍
이제 4단계 하나만 남았네요!

코멘트 몇개 남겨드렸으니 다음미션 진행하면서 같이 확인하시면 좋을것같습니다 ㅎㅎ
조금만 더 화이팅입니다!

@limwoobin limwoobin merged commit 105f996 into next-step:gyeom Dec 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants