Skip to content

Conversation

@goohong
Copy link
Owner

@goohong goohong commented Nov 12, 2024

Class Diagram

@goohong goohong changed the title [편의점] 정구홍 코드리뷰 [편의점] 정구홍 코드리뷰입니다. Nov 15, 2024
Copy link

@ghkgus ghkgus left a comment

Choose a reason for hiding this comment

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

전체적으로 코드가 깔끔하고 이해하기 쉽게 작성된 것 같습니다. 배울 점이 많았던 코드였고, 4주 동안 수고 많으셨습니다!


String[] parts = item.substring(START_INDEX, item.length() - END_INDEX_OFFSET).trim().split(ITEM_DELIMITER);
validateProductAndQuantityFormat(parts);

Copy link

Choose a reason for hiding this comment

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

메서드가 조금 긴거 같아요 함수parts함수와 productName 메서드를 분리해, 검증해 반환하는 로직을 작성하는건 어떨까요?

Copy link
Owner Author

Choose a reason for hiding this comment

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

좋은 의견이신 것 같습니다 👍



private static boolean isRemaining(int quantity) {
return quantity > MIN_QUANTITY;
Copy link

Choose a reason for hiding this comment

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

static을 사용할 이유가 없어보입니다!

outputView.printProducts(productDTOs);

Orders orders = retryUntilValid(() -> createOrders(productDTOs));
Receipt receipt = processOrders(orders);
Copy link

Choose a reason for hiding this comment

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

함수형 포인트를 사용하시니 코드가 정말 깔끔하네요.. 감탄하고 갑니다,,

for (OrderDTO orderDTO : orders.getOrderDTOs()) {
OrderProcessor orderProcessor = new OrderProcessor(products, promotions, orderDTO);

if (orderProcessor.promotionIsNotAvailable()) {
Copy link

Choose a reason for hiding this comment

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

메서드 명은 동사나 전치사 시작을 추천드립니다!


private int getPromotionGetQuantity() {
return availableQuantity / (buy + get) * (get);
}
Copy link

Choose a reason for hiding this comment

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

목적에 맞게 잘 나누 신거 같네요,, 저도 분리할껄 그랬나봐요ㅜㅜ 배우고 갑니다...

}
}

public boolean promotionIsNotAvailable() {
Copy link

Choose a reason for hiding this comment

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

이 부분도 명사대신 동사나 전치사로 시작하는게 좋을 거 같습니다!

Copy link

@SeongUk52 SeongUk52 left a comment

Choose a reason for hiding this comment

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

DTO를 활용하여 깔끔하게 잘 구현하셨네요
마지막 미션 고생 많으셨습니다

InputConverter inputConverter = new InputConverter();

return new StoreController(inputView, outputView, inputConverter, products, promotions
);

Choose a reason for hiding this comment

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

AppConfig같은 외부 클래스에 구현하셔도 좋을 것 같습니다

Comment on lines +25 to +35
public StoreController(InputView inputView,
OutputView outputView,
InputConverter inputConverter,
Products products,
Promotions promotions) {
this.inputView = inputView;
this.outputView = outputView;
this.inputConverter = inputConverter;
this.products = products;
this.promotions = promotions;
}

Choose a reason for hiding this comment

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

메서드에 파라미터 5개는 너무 많다고 생각해요

Copy link
Owner Author

Choose a reason for hiding this comment

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

다른 객체였다면 빌더 패턴 같은 것을 고려해보았을 것 같은데 컨트롤러다 보니 의존성 주입 시에 보여지는 부분을 신경쓰지 않은 것 같습니다.

Comment on lines +5 to +12
public record PromotionDTO(
String name,
int buy,
int get,
LocalDate startDate,
LocalDate endDate
) {
}

Choose a reason for hiding this comment

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

레코드를 활용하여 DTO를 간단하게 구현하셨네요 👍

Comment on lines +29 to +51
public List<String> generateReceipt() {
List<String> receipt = new ArrayList<>();
int totalAmount = 0;
int totalQuantity = 0;
int promotionDiscount = 0;
int membershipDiscount = 0;

addReceiptHeader(receipt);

int[] totals = addProductsToReceipt(receipt, totalAmount, totalQuantity);
totalAmount = totals[TOTAL_AMOUNT_INDEX];
totalQuantity = totals[TOTAL_QUANTITY_INDEX];

promotionDiscount = addPromotionsToReceipt(receipt, promotionDiscount);

if (applyMembershipDiscount) {
membershipDiscount = calculateMembershipDiscount(totalAmount, promotionDiscount);
}

addReceiptFooter(receipt, totalAmount, totalQuantity, promotionDiscount, membershipDiscount);

return receipt;
}

Choose a reason for hiding this comment

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

메서드의 길이가 너무 긴 것 같습니다

Copy link

@yeong0jae yeong0jae left a comment

Choose a reason for hiding this comment

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

4주차 고생하셨어요~
너무 잘하시네요. 제가 리뷰 남길 부분이 많지 않네요.. 많이 배워갑니다..!
좋은 결과 있으시길 바랍니다!

productDTO.quantity(),
productDTO.promotion())
);
}

Choose a reason for hiding this comment

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

이 부분은 스트림을 사용하지 않으신 이유가 있을까요?

if (input == null || input.trim().isEmpty()) {
throw new IllegalArgumentException(ErrorCode.GENERAL_INVALID_INPUT.getMessage());
}
}

Choose a reason for hiding this comment

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

유효성 검사 정말 꼼꼼하네요!

}

protected abstract T parseLine(String line);
}

Choose a reason for hiding this comment

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

새로운 데이터 형식이 추가되더라도 parseLine만 구현하면 된다는 구조가 너무 좋네요.
배워갑니다!!


return String.format(PRODUCT_FORMAT_WITH_PROMOTION, name, price, quantity, promotion);
}
}

Choose a reason for hiding this comment

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

영수증 출력 로직 정말 깔끔하네요..!
모델에 의존하지 않고 데이터만 받아서 출력하는 것도 좋네요.

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.

5 participants